TCP 并发服务器 select实现

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>#define ERR_MSG(msg) do{\fprintf(stderr,"line=__%d__",__LINE__);\perror(msg);\
}while(0)//服务器地址+端口
#define SER_PORT 2222 //1024~49151
#define SER_IP "192.168.31.200" int main(int argc, const char *argv[])
{ //创建一个新的套接字int sfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == sfd){ERR_MSG("socket");return -1;}printf("sfd=%d\n",sfd);//设置套接字选项int reuse = 1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("setsockopt success\n");//地址信息结构体struct sockaddr_in sin;//IPV4 地址簇sin.sin_family = AF_INET;//将端口号从主机字节序转成网络字节序sin.sin_port = htons(SER_PORT);//将IPV4地址的字符串转换为网络字节序的整数sin.sin_addr.s_addr = inet_addr(SER_IP);//将IP地址和端口号绑定到指定套接字中if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success\n");//将套接字设置为被动监听状态,只负责监听是否有客户端连接成功if(listen(sfd,10) < 0){ERR_MSG("listen");return -1;}printf("listen success\n");fd_set readfds,tempfds;int maxfd = sfd;FD_ZERO(&readfds);FD_ZERO(&tempfds);FD_SET(0,&readfds);FD_SET(sfd,&readfds);int s_res = 0;int newfd = -1;ssize_t res = 0;char buf[128] = "";//存储客户端的地址信息int dtablesize = getdtablesize();struct sockaddr_in clients[dtablesize-4];//0 1 2 sfdstruct sockaddr_in cin;socklen_t addrlen = sizeof(cin);while(1){tempfds = readfds;s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);if(s_res < 0){ERR_MSG("select");return -1;}else if(0 == s_res){printf("time out\n");break;}for(int i=0;i<=maxfd;i++){if(FD_ISSET(i,&tempfds) == 0){continue;}if(0 == i){//键盘触发int sndfd;res = scanf("%d %s",&sndfd,buf);while(getchar() != 10);if(res != 2){fprintf(stderr,"请输入正确格式:文件描述符 内容\n");continue;}if( sndfd >= dtablesize || sndfd <= sfd || !FD_ISSET(sndfd,&readfds) ){fprintf(stderr,"sndfd=%d 没有对应的客户端\n",sndfd);continue;}if(send(sndfd,buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}printf("send success\n");}else if(sfd == i){//触发客户端连接newfd = accept(sfd,(struct sockaddr *)&cin,&addrlen);if(newfd < 0){ERR_MSG("accept");return -1;}printf("newfd=%d\n",newfd);printf("[%s:%d]\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));clients[newfd-4] = cin;FD_SET(newfd,&readfds);maxfd = maxfd>newfd?maxfd:newfd;}else{//触发客户端交互事件bzero(buf,sizeof(buf));//从一个已经连接的socket接收数据res = read(i,buf,sizeof(buf));if(res < 0){//=-1 运行失败ERR_MSG("recv");}else if(0 == res){fprintf(stderr,"[%s:%d] 客户端断开连接\n",\inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port));close(i);FD_CLR(i,&readfds);for(int j=maxfd;j>sfd;j--){if(FD_ISSET(j,&readfds)){maxfd = j;break;}}}else{printf("rcv [%s:%d] newfd=%d buf=%s\n",\inet_ntoa(clients[i-4].sin_addr),\ntohs(clients[i-4].sin_port),i,buf);  //发送---->谁发给我数据,我就发还给谁strcat(buf,"*_*");//将数据发送给指定的套接字文件描述符中if(send(i,buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}printf("send success\n");}}}}close(sfd);return 0;
}

TCP 并发客户端 select实现

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>#define ERR_MSG(msg) do{\fprintf(stderr,"line=__%d__",__LINE__);\perror(msg);\
}while(0)//服务器地址+端口
#define SER_PORT 2222 //1024~49151
#define SER_IP "192.168.31.200" int main(int argc, const char *argv[])
{ //创建一个新的套接字int sfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == sfd){ERR_MSG("socket");return -1;}printf("sfd=%d\n",sfd);//设置套接字选项int reuse = 1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("setsockopt success\n");//地址信息结构体struct sockaddr_in sin;//IPV4 地址簇sin.sin_family = AF_INET;//将端口号从主机字节序转成网络字节序sin.sin_port = htons(SER_PORT);//将IPV4地址的字符串转换为网络字节序的整数sin.sin_addr.s_addr = inet_addr(SER_IP);//将IP地址和端口号绑定到指定套接字中if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success\n");//将套接字设置为被动监听状态,只负责监听是否有客户端连接成功if(listen(sfd,10) < 0){ERR_MSG("listen");return -1;}printf("listen success\n");fd_set readfds,tempfds;int maxfd = sfd;FD_ZERO(&readfds);FD_ZERO(&tempfds);FD_SET(0,&readfds);FD_SET(sfd,&readfds);int s_res = 0;int newfd = -1;ssize_t res = 0;char buf[128] = "";//存储客户端的地址信息int dtablesize = getdtablesize();struct sockaddr_in clients[dtablesize-4];//0 1 2 sfdstruct sockaddr_in cin;socklen_t addrlen = sizeof(cin);while(1){tempfds = readfds;s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);if(s_res < 0){ERR_MSG("select");return -1;}else if(0 == s_res){printf("time out\n");break;}for(int i=0;i<=maxfd;i++){if(FD_ISSET(i,&tempfds) == 0){continue;}if(0 == i){//键盘触发int sndfd;res = scanf("%d %s",&sndfd,buf);while(getchar() != 10);if(res != 2){fprintf(stderr,"请输入正确格式:文件描述符 内容\n");continue;}if( sndfd >= dtablesize || sndfd <= sfd || !FD_ISSET(sndfd,&readfds) ){fprintf(stderr,"sndfd=%d 没有对应的客户端\n",sndfd);continue;}if(send(sndfd,buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}printf("send success\n");}else if(sfd == i){//触发客户端连接newfd = accept(sfd,(struct sockaddr *)&cin,&addrlen);if(newfd < 0){ERR_MSG("accept");return -1;}printf("newfd=%d\n",newfd);printf("[%s:%d]\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));clients[newfd-4] = cin;FD_SET(newfd,&readfds);maxfd = maxfd>newfd?maxfd:newfd;}else{//触发客户端交互事件bzero(buf,sizeof(buf));//从一个已经连接的socket接收数据res = read(i,buf,sizeof(buf));if(res < 0){//=-1 运行失败ERR_MSG("recv");}else if(0 == res){fprintf(stderr,"[%s:%d] 客户端断开连接\n",\inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port));close(i);FD_CLR(i,&readfds);for(int j=maxfd;j>sfd;j--){if(FD_ISSET(j,&readfds)){maxfd = j;break;}}}else{printf("rcv [%s:%d] newfd=%d buf=%s\n",\inet_ntoa(clients[i-4].sin_addr),\ntohs(clients[i-4].sin_port),i,buf);  //发送---->谁发给我数据,我就发还给谁strcat(buf,"*_*");//将数据发送给指定的套接字文件描述符中if(send(i,buf,sizeof(buf),0) < 0){ERR_MSG("send");return -1;}printf("send success\n");}}}}close(sfd);return 0;
}

TCP 并发客户端 poll实现

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>#define ERR_MSG(msg) do{\fprintf(stderr,"line=__%d__",__LINE__);\perror(msg);\
}while(0)#define SER_PORT 2222 //1024~49151
#define SER_IP "192.168.31.200" #define CLI_PORT 4444
#define CLI_IP "192.168.31.200" int main(int argc, const char *argv[])
{ //创建套接字int cfd = socket(AF_INET,SOCK_STREAM,0);if(cfd < 0){ERR_MSG("socket");return -1;}//客户端信息结构体struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(CLI_PORT);cin.sin_addr.s_addr = inet_addr(CLI_IP);//bind 将ip地址和端口号绑定到指定套接字 非必须绑定if(bind(cfd,(struct sockaddr *)&cin,sizeof(cin)) < 0){ERR_MSG("bind");return -1;}printf("client bind success\n");//服务器端结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);//连接服务器//int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);if(connect(cfd,(struct sockaddr *)&sin,sizeof(sin)) < 0){ERR_MSG("connect");return -1;}printf("connect server success\n");char buf[128];ssize_t res = 0;struct pollfd fds[2];fds[0].fd = 0;fds[0].events = POLLIN;fds[1].fd = cfd;fds[1].events = POLLIN;int p_res = 0 ;while(1){p_res = poll(fds,2,-1);if(p_res < 0){ERR_MSG("poll");return -1;}else if(0 == p_res){printf("time out\n");break;}if(fds[0].revents&POLLIN){bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = 0;//发送信息if(send(cfd , buf , sizeof(buf),0) < 0){ERR_MSG("send");return -1;}printf("send success\n");}if(fds[1].revents&POLLIN){bzero(buf,sizeof(buf));//接收信息res = recv(cfd,buf,sizeof(buf),0);if(res < 0){ERR_MSG("recv");return -1;}else if( 0 == res){printf("sever close!\n");break;}printf("rcv buf = %s\n",buf);}}close(cfd);return 0;
}

20230316 作业相关推荐

  1. LeetCode简单题之在既定时间做作业的学生人数

    题目 给你两个整数数组 startTime(开始时间)和 endTime(结束时间),并指定一个整数 queryTime 作为查询时间. 已知,第 i 名学生在 startTime[i] 时开始写作业 ...

  2. 作业函数的定义与调用

    作业函数的定义与调用 在 OneFlow 中,将训练.预测任务封装在一个函数中,统称为作业函数(job function),作业函数联系用户的业务逻辑与 OneFlow 管理的计算资源. 在 OneF ...

  3. 华东理工大学计算机应用基础,最新华东理工大学计算机应用基础网上作业及全部答案...

    精品文档 华东理工大学计算机应用基础网上作业及全部答案 2012计算机应用基础答案: 一.选择题 1.文件夹是用来对应用程序.文件进行分组的,以下说法中()正确.答:一个文件夹内可以包含文件.应用程序 ...

  4. 《小团团团队》第五次作业:项目需求分析改进与系统设计

    项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 实验九 团队作业5-团队项目需求改进与系统设计 团队名称 小团团团队 作业学习目标 (1)掌握面向对象需求分析方法:(2) ...

  5. 2017级面向对象程序设计 作业三

    Deadline:2018-05-13 22:00pm 题目升级 一栋10层的大楼(楼层编号1-10),设3台无限载重的电梯,初始时电梯停在1层.其中:1号电梯只能停留在奇数层,2号电梯可以各层都停留 ...

  6. 201621123068 作业08-集合

    1. 本周学习总结 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的<contains>源代码 答:源代码 public boolean contains ...

  7. 代码管理和版本管理的作业流程以及规范是怎样的?

    代码管理和版本管理的作业流程以及规范是怎样的? 代码管理和版本管理的作业流程以及规范是怎样的?下面以文档的形式进行详细分析,希望能够给予测试人员一些帮助和指导. 本文目的 本文试图提供一套有效进行代码 ...

  8. 结队项目——第一次作业

    By: 031502220 计算机二班 李自强031502344 计算机三班 郑世强 Table of Contents 一 需求分析:二 具体设计:三 系统功能说明:四 产品优劣势分析:五 PSP: ...

  9. 第三次作业+105032014085

    对修正后第2次作业+105032014141的单元测试 1.修正后的流程图 2.测试用例设计 3.单元测试框架 1 import static org.junit.Assert.*; 2 3 impo ...

最新文章

  1. 计算机课做ppt的软件有哪些内容,课程内容计算机软件的基础知识.ppt
  2. Newtonsoft.Json的简单使用
  3. Entity Framework
  4. HTML里的哪一部分Javascript 会在页面加载的时候被执行?
  5. [2020-11-30 contest]数列(矩阵加速),秘密通道(dijkstra最短路)小X游世界树(换根dp),划分(数学)
  6. vscode弹出cmd_先看看 VS Code Extension 知识点,再写个 VS Code 扩展玩玩
  7. leetcode python3 简单题219. Contains Duplicate II
  8. Python学习Day7
  9. 【综述阅读】Ad hoc网络路由相关的几篇综述
  10. 标竿学习 - 一项有效的管理工具(转载)
  11. msfconsole 控制台简介
  12. xp计算机图标怎么设置在桌面显示,电脑系统是XP的,界面的“我的电脑”图标不知怎么变成快捷方式了...
  13. 两台计算机互相共享一个网络,两台电脑共用一个路由器上网,但两台电脑不能互相访问共享,怎样设置啊?两台电脑系统都XP的...
  14. linux man 位置,Linux系统如何查看命令帮助,man命令使用详解
  15. Android源码编译:任意界面屏幕边缘上滑弹出快捷操作栏【一键加速、开关控制】
  16. 《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一2.15圆形构图
  17. Linux nodejs 安装以及配置环境
  18. 模式先行全新解读微商分销系统
  19. 交换DataFrame的两列
  20. Wireshark抓包以及tcpdump抓包

热门文章

  1. 遥感智能解译相关产品及公司
  2. nefu--15--八阵图
  3. 电脑读卡器,笔记本读卡器怎么用教程
  4. declval 的说明
  5. win10 android ios,一机多用?Win10可运行安卓和iOS应用
  6. 桌面窗口管理器占用内存过高解决办法
  7. 15、ESP-MESH组网
  8. vue如何设置 网页标题 关键字 描述
  9. 个人总结感想系列 - 2013年工作和生活总结
  10. 第四天:基础入门-30余种加密编码进制Web数据库系统代码参数值