多线程并发C/S基本通信模型及实现
2016-02-20 15:18
357 查看
本例实现如下功能:
服务端接收来自客户端发送过来的字符串,将小写转换为大写后发送回客户端。
其中,每一个新客户端连接后,服务端主进程为此客户端创建一个线程进行数据的处理。
多线程并发服务端:
多线程并发客户端
执行测试:
新开一终端打开一个客户端:
再新开一终端打开一个客户端:
服务端接收来自客户端发送过来的字符串,将小写转换为大写后发送回客户端。
其中,每一个新客户端连接后,服务端主进程为此客户端创建一个线程进行数据的处理。
多线程并发服务端:
/*server.c*/ #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #define BUFSIZE 666 #define SERV_PORT 8888 #define MAX 200 //本例线程最大个数设为200 /*与服务端通信的客户端地址及通信文件描述符的信息结构*/ struct s_info{ struct sockaddr_in cliaddr; int connfd; }; void *work(void *arg) { int n, i; struct s_info *ts = (struct s_info*)arg; char buf[BUFSIZE]; char str[INET_ADDRSTRLEN]; /*线程资源回收*/ pthread_detach(pthread_self()); while(1){ /*读取数据*/ n = read(ts->connfd, buf, BUFSIZE); if(n == 0 ){ printf("另一端已关闭\n"); break; } printf("从地址%s端口%d接收到数据\n", inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)), ntohs((*ts).cliaddr.sin_port)); for(i = 0; i<n; i++) /*小写转为大写*/ buf[i] = toupper(buf[i]); /*将buf写入文件描述符ts->connfd*/ write(ts->connfd, buf, n); } close(ts->connfd); return; } int main(void) { struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; int listenfd, connfd; int i = 0; pthread_t tid;/*线程id*/ struct s_info ts[MAX]; /*创建通信socket*/ listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); /*socket绑定服务端地址*/ bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); /*监听*/ listen(listenfd, 20); printf("等待连接:\n"); while(1){ cliaddr_len = sizeof(cliaddr); /*接收客户端请求*/ connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddr_len); ts[i].cliaddr = cliaddr; ts[i].connfd = connfd; /*创建线程处理客户端请求*/ pthread_create(&tid, NULL, work, (void*)&ts[i]); i++; } return 0; }
多线程并发客户端
/*client.c*/ #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #define BUFSIZE 666 #define SERV_PORT 8888 int main(int argc, char*argv[]) { struct sockaddr_in servaddr; char buf[BUFSIZE]; int sockfd, n; sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr); servaddr.sin_port = htons(SERV_PORT); /*连接*/ connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); while(fgets(buf, BUFSIZE, stdin) != NULL){ /*向通信sockfd写入数据buf*/ write(sockfd, buf, strlen(buf)); /*接收服务端数据*/ n = read(sockfd, buf, BUFSIZE); if(n == 0){ printf("服务器已关闭\n"); }else{ write(STDOUT_FILENO, buf, n); } } close(sockfd); return 0; }
执行测试:
yu@ubuntu:~/Linux/220/duoxiancheng$ gcc -o server server.c -lpthread yu@ubuntu:~/Linux/220/duoxiancheng$ gcc -o client client.c yu@ubuntu:~/Linux/220/duoxiancheng$ ./server 等待连接: 从地址127.0.0.1端口32878接收到数据 从地址127.0.0.1端口32878接收到数据 从地址127.0.0.1端口32879接收到数据 从地址127.0.0.1端口32879接收到数据
新开一终端打开一个客户端:
yu@ubuntu:~/Linux/220/duoxiancheng$ ./client jintian JINTIAN heheda HEHEDA
再新开一终端打开一个客户端:
yu@ubuntu:~/Linux/220/duoxiancheng$ ./client nihao a NIHAO A haode zaijian HAODE ZAIJIAN
相关文章推荐
- Java工具类之配置文件读取
- BSOJ1850:POJ1474摄像头 计算几何 半平面交
- 三层架构的基础知识
- ANDROID_MARS学习笔记_S03_003_LocationManager、LocationListener
- python 解析xml包使用方法总结
- iOS UIView及其子控件的常用设置
- Angular2学习笔记.3、通过模板调用Controller事件实现用户输入和显示,UserInput
- Cocos2d-x 3.x事件机制源码分析
- Swift实现自定义的UITabBarController
- 1020. Tree Traversals (25)
- 线程池特性的实例检验
- flv文件AVCDecoderConfigurationRecord以及AudioSpecificConfig结构
- textview 滚动显示.txt
- android app 读取本地.db文件,实现不变数据本地化(附小demo)
- 【Hibernate】映射关系总结
- OpenGL几种绘制方式
- UML的关联(Association), 聚合(Aggregation), 组合(Composition)区别
- mybatis批量插入、批量删除
- HDU 4763 Theme Section
- php的一些魔术方法的使用