socket学习笔记——线程(聊天程序)
server.c
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h> #define BUF_SIZE 100
#define MAX_CLNT 256 void *handle_clnt(void* arg);
void send_msg(char *msg,int len);
void error_handling(char* message); int clnt_cnt = ;
int clnt_socks[MAX_CLNT];
pthread_mutex_t mutx; int main(int argc,char* argv[])
{
int serv_sock,clnt_sock;
struct sockaddr_in serv_addr,clnt_addr;
int adr_sz;
pthread_t t_id; if(argc != )
{
printf("usage: %s <port>\n",argv[]);
exit();
} pthread_mutex_init(&mutx,NULL);
serv_sock = socket(PF_INET,SOCK_STREAM,);
memset(&serv_addr,,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[])); if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -)
error_handling("bind error");
if(listen(serv_sock,) == -)
error_handling("listen error"); while()
{
adr_sz = sizeof(clnt_addr);
clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&adr_sz); pthread_mutex_lock(&mutx);
clnt_socks[clnt_cnt++] = clnt_sock;
pthread_mutex_unlock(&mutx); pthread_create(&t_id,NULL,handle_clnt,(void*)&clnt_sock);
pthread_detach(t_id);
printf("connected client ip:%s \n",inet_ntoa(clnt_addr.sin_addr));
}
close(serv_sock);
return ;
} void* handle_clnt(void* arg)
{
int clnt_sock = *((int*)arg);
int str_len = ,i;
char msg[BUF_SIZE]; while((str_len = read(clnt_sock,msg,sizeof(msg))) != )
send_msg(msg,str_len);
pthread_mutex_lock(&mutx);
for(i = ;i < clnt_cnt;i++)
{
if(clnt_sock == clnt_socks[i])
{
while(i++ < clnt_cnt-)
clnt_socks[i] = clnt_socks[i+];
break;
}
}
clnt_cnt--;
pthread_mutex_unlock(&mutx);
close(clnt_sock);
return NULL;
} void send_msg(char* msg,int len)
{
int i;
pthread_mutex_lock(&mutx);
for(i = ;i < clnt_cnt;i++)
write(clnt_socks[i],msg,len);
pthread_mutex_unlock(&mutx);
}
void error_handling(char* message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit();
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/socket.h> #define BUF_SIZE 200
#define NAME_SIZE 20 void *send_msg(void* arg);
void *recv_msg(void* arg);
void error_handling(char* message); char name[NAME_SIZE] = "[DEFAULT]";
char msg[BUF_SIZE];
int main(int argc,char* argv[])
{
int sock;
struct sockaddr_in serv_addr;
pthread_t send_thread,recv_thread;
void * thread_return; if(argc != )
{
printf("usage: %s <ip> <port> <name>\n");
exit();
} sprintf(name,"[%s]",argv[]);
sock = socket(PF_INET,SOCK_STREAM,); memset(&serv_addr,,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[]);
serv_addr.sin_port = htons(atoi(argv[])); if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -)
error_handling("connect error"); pthread_create(&send_thread,NULL,send_msg,(void*)&sock);
pthread_create(&recv_thread,NULL,recv_msg,(void*)&sock);
pthread_join(send_thread,&thread_return);
pthread_join(recv_thread,&thread_return);
close(sock);
return ;
} void* send_msg(void* arg)
{
int sock = *((int*)arg);
char name_msg[NAME_SIZE+BUF_SIZE];
while()
{
fgets(msg,BUF_SIZE,stdin);
if(!strcmp(msg,"q\n") || !strcmp(msg,"Q\n"))
{
close(sock);
exit();
}
sprintf(name_msg,"%s %s",name,msg);
write(sock,name_msg,strlen(name_msg));
}
return NULL;
} void* recv_msg(void* arg)
{
int sock = *((int*)arg);
char name_msg[BUF_SIZE+NAME_SIZE];
int str_len;
while()
{
str_len = read(sock,name_msg,NAME_SIZE+BUF_SIZE-);
if(str_len == -)
return (void*)-;
name_msg[str_len] = ;
fputs(name_msg,stdout);
}
return NULL;
} void error_handling(char* message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit();
}
socket学习笔记——线程(聊天程序)的更多相关文章
- java swing+socket实现多人聊天程序
swing+socket实现多人聊天程序 1.准备工作 先看效果: 客户端项目结构图: 服务端项目结构图: 2.运行原理 服务端 先开一个线程serverListerner,线程中开启一个Server ...
- JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?
前言:休整一个多月之后,终于开始投简历了.这段时间休息了一阵子,又病了几天,真正用来复习准备的时间其实并不多.说实话,心里不是非常有底气. 这可能是学生时代遗留的思维惯性--总想着做好万全准备才去做事 ...
- Android IPC机制(五)用Socket实现跨进程聊天程序
1.Socket简介 Socket也称作“套接字“,是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信.它分为流式套接字和数据包套接 ...
- SYSBIOS学习笔记---线程(Threads)
在SYS/BIOS中,广义上指被处理器执行的任何独立的指令流.线程是一个能够调用一个函数或者中断服务程序的单点控制.在sysbios系统中一共有硬件中断(HWI).软件中断(SWI).任务(Task) ...
- Java Socket 学习笔记
TCP协议的Socket编程 Socket:英文中的意思是插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket.Java中所有关于网络编程的类都 ...
- [快手(AAuto)学习笔记]如何让程序在运行时请求管理员权限(UAC)
作者:ffsystem 作为(糟糕的)程序猿,习惯写代码解决一些简单事务.正常用批处理就能解决大部分工作,复杂一点用AutoIt 3. 有时候要分发给别人,就需要一个界面.外行你程序写得如何他看不懂, ...
- 微信小程序学习笔记一 小程序介绍 & 前置知识
微信小程序学习笔记一 1. 什么是小程序? 2017年度百度百科十大热词之一 微信小程序, 简称小程序, 英文名 Mini Program, 是一种不需要下载安装即可使用的应用 ( 张小龙对其的定义是 ...
- linux学习笔记:vim程序编辑器—vim的使用
注:以下是学习<鸟哥的linux私房菜>(第三版)的学习笔记,纯属个人学习记录. 2018-11-19 一.学习vim的原因 很多软件的编辑接口都会主动调用vi 二.vim的使用 (1)v ...
- Java学习笔记——线程
线程: 定义:线程是程序内的一个单一的顺序控制流程,也被称为“轻型进程(lightweight process)” 或“执行上下文(execution context )” 线程用于分隔任务 线程类似 ...
随机推荐
- android学习笔记48——SQLite
SQLite SQLite试试一个嵌入式的数据库引擎,专门用于资源有限的设备(如手机.PDA)上适量数据存取. SQLite支持绝大部分SQL92语法,同样允许开发者使用SQL语句操作数据库中的数据, ...
- 无法找到类:java.lang.ClassNotFoundException: com.tt.javaweb.HttpServletRequest问题解决
问题如下:找不到Httpservlet对应的Class,进入build目录下发现确实没有对应的class文件. 严重: Allocate exception for HttpServletReques ...
- linux awk命令
简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...
- Android Please ensure that adb is correctly located at问题解决
转载于:http://breezylee.iteye.com/blog/2032588 遇到问题描述: 运行android程序控制台输出 [2012-07-18 16:18:26 - ] The co ...
- 只有一个Service或Broadcast Reciver的android应用
Service是android四大组件中与Activity最相似的组件,都可以代表可执行的程序. Service与Activity的区别在于: (1).Service一直在后台运行,没有用户界面. ...
- MDK+硬件仿真器实现debugprintf()-stm32
MDK+硬件仿真器实现debugprintf()-stm32 1MDK工程设置如下 2其中stm32debug.ini文件内容为 /********************************** ...
- jQuery-ajax: 取消关注|关注
ylbtech-jQuery-ajax: 取消关注|关注 1.A,jQuery-效果图返回顶部 1.B,jQuery-Source Code(源代码)返回顶部 <script src=&qu ...
- JAVA 类中方法参数与返回值
无参无返回值的方法,用public void 方法名,来声明: 有参无返回值的方法,用public void 方法名,来声明: 有参有返回值的方法,用public int 方法名(int i,int ...
- google protobuf 简单实例
1.定义proto文件: User.proto package netty; option java_package="myprotobuf"; option java_outer ...
- ruby1.8到2.1语法改变
1定义hash的语法改变old_way = {:foo => "bar", :one => 1}new_way = {foo: "bar", one ...