当前位置: 首页 > news >正文

国庆作业2

select实现服务器并发

代码: 

#include <myhead.h>#define ERR_MSG(msg) do{\printf("%d\n",__LINE__);\perror(msg);\
}while(0)#define PORT 8888#define IP "192.168.1.5"int main(int argc, const char *argv[])
{//创建流式套接字 socketint sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd == -1){ERR_MSG("socket");return -1;}printf("socket create success! sfd = %d\n",sfd);//允许端口快速的被复用int reuse = 1;                                                            if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速的被复用成功\n");//绑定服务器的地址信息 --->必须绑定 bindstruct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) == -1){ERR_MSG("bind");return -1;}printf("bind success!\n");//将套接字设置为被动监听状态 listenif(listen(sfd,128) == -1){ERR_MSG("listen");return -1;}printf("listen success!\n");fd_set readfds,tempfds;//清空集合FD_ZERO(&readfds);//添加文件描述符FD_SET(0,&readfds);FD_SET(sfd,&readfds);struct sockaddr_in cin;socklen_t addrlen = sizeof(cin);int newfd = -1;char buf[32];ssize_t res = 0;int s_res = -1;int maxfd = sfd;int sndfd = -1;struct sockaddr_in save[1024];while(1){tempfds = readfds;maxfd = maxfd>newfd?maxfd:newfd;s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);if(s_res == -1){ERR_MSG("select");return -1;}else if(s_res == 0){printf("time out\n");break;}for(int i = 0;i <= maxfd;i++){if(FD_ISSET(i,&tempfds) == 0)continue;if(0 == i){printf("触发键盘输入事件\n");bzero(buf,sizeof(buf));int ret = scanf("%d %s",&sndfd,buf);if(ret != 2){printf("您的输入格式有误:sndfd buf\n");return -1;}if(sndfd <= 2 || FD_ISSET(sndfd,&readfds) == 0){printf("您输入的文件描述符不合法 snfd = %d\n",sndfd);return -1;}//发送if(send(sndfd,buf,sizeof(buf),0) == -1){ERR_MSG("send");return -1;}printf("send success!\n");}else if(sfd == i){printf("触发客户端连接事件\n");//获取一个已经完成的客户端信息,生成一个新的文件描述符 acceptnewfd = accept(sfd,(struct sockaddr*)&cin,&addrlen); if(newfd == -1){ERR_MSG("accept");return -1;}printf("[%s:%d]客户端链接成功! newfd = %d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);save[newfd] = cin;FD_SET(newfd,&readfds);}else{printf("触发接收客户端数据事件\n");//接收bzero(buf,sizeof(buf));res = recv(i,buf,sizeof(buf),0);if(res == -1){ERR_MSG("recv");return -1;}else if(res == 0){printf("[%s:%d]客户端已下线! newfd = %d\n",inet_ntoa(save[i].sin_addr),ntohs(save[i].sin_port),i);close(i);FD_CLR(i,&readfds);while(FD_ISSET(maxfd,&readfds) == 0 && maxfd-->=0);continue;}printf("[%s:%d] newfd = %d buf = %s \n",inet_ntoa(save[i].sin_addr),ntohs(save[i].sin_port),i,buf);//发送if(send(i,buf,sizeof(buf),0) == -1){ERR_MSG("send");return -1;}printf("send success!\n");}}}//关闭文件描述符if(close(sfd)<0){ERR_MSG("close");return -1;}if(close(newfd) < 0){ERR_MSG("close");return -1;}return 0;
}

运行效果

http://www.lryc.cn/news/179878.html

相关文章:

  • fork仓库的代码如何同步主仓库代码
  • 【Axure】元件库和母版、常见的原型规范、静态原型页面制作
  • 在设备树中描述中断
  • ccf_csp第一题汇总
  • uniapp 实现下拉筛选框 二次开发定制
  • 实现单行/多行文本溢出
  • Spring Boot中的Binder类
  • leetcode之打家劫舍
  • 走进Spring的世界 —— Spring底层核心原理解析(一)
  • 快看看你的手机有没有:谷歌Android全面封杀此类软件!
  • spark ui 指南
  • 【分布式事务】
  • linux 清除卸载jenkins
  • 番外4:VMware安装
  • Oracle 19.20 patch 注意事项
  • ElementUI之增删改及表单验证
  • 【Java 进阶篇】深入理解 JDBC:Java 数据库连接详解
  • Web开发-session介绍
  • 基于Qt Creator开发的坦克大战小游戏
  • 小说推文和短剧推广以及电影达人带货电影票
  • 朴素贝叶斯分类(下):数据挖掘十大算法之一
  • 9.30作业
  • [GWCTF 2019]枯燥的抽奖
  • vue3中sync修饰符的使用
  • Qt全屏显示与退出
  • OpenCV之直线曲线拟合
  • 2023年哪款PDF虚拟打印机好用?
  • Redis各数据类型特定的命令和用法 1.0版本
  • 卫星图像应用 - 洪水检测 使用DALI进行数据预处理
  • 为什么字节大量用GO而不是Java?