TCP的poll多路复用实现群聊

news/2024/10/17 21:17:34/

 服务器

#include <myhead.h>
#define SERIP "192.168.125.99"
#define SERPORT 9999
int main(int argc, const char *argv[])
{int sfd=-1;if((sfd=socket(AF_INET,SOCK_STREAM,0))==-1){perror("socket error");return -1;}printf("sfd=%d\n",sfd);int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt error");return -1;}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SERPORT);sin.sin_addr.s_addr=inet_addr(SERIP);struct sockaddr_in cin;socklen_t socklen=sizeof(cin);struct sockaddr_in newsin[1024];char name[1024][128];if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind error");return -1;}printf("bind success\n");if(listen(sfd,128)==-1){perror("listen error");return -1;}printf("listen success\n");int res=-1;char rbuf[128]="";char wbuf[128]="";struct pollfd fds[1024];for(int i=0;i<1024;i++){fds[i].fd=-1;fds[i].events=POLLIN;}fds[0].fd=0;fds[0].events=POLLIN;//insert_rear("服务器输入",head);fds[3].fd=sfd;fds[3].events=POLLIN;//insert_rear("连接用",head);while(1){res=poll(fds,1024,-1);if(res<0){perror("poll error");return -1;}else if(res==0){printf("time out\n");return -1;}if(fds[0].revents==POLLIN){bzero(rbuf,sizeof(rbuf));bzero(wbuf,sizeof(wbuf));fgets(rbuf,sizeof(rbuf),stdin);rbuf[strlen(rbuf)-1]=0;strcat(wbuf,"服务器: ");strcat(wbuf,rbuf);strcpy(rbuf,wbuf);for(int i=4;i<1024;i++){send(fds[i].fd,rbuf,sizeof(rbuf),0);}}//负责连接else if(fds[3].revents==POLLIN){int newfd=-1;if((newfd=accept(sfd,(struct sockaddr*)&cin,&socklen))==-1){perror("connect error");return -1;}newsin[newfd]=cin;printf("[%s:%d]connect success\n",inet_ntoa(newsin[newfd].sin_addr),ntohs(newsin[newfd].sin_port));fds[newfd].fd=newfd;}for(int i=4;i<1024;i++){//服务器端输入if(fds[i].revents!=POLLIN){continue;}{		//表示其余待触发poll	bzero(rbuf,sizeof(rbuf));char lbuf[128]="";int f=recv(fds[i].fd,rbuf,sizeof(rbuf),0);if(rbuf[0]=='N'){char *p=rbuf;p=p+1;strcpy(name[i],p);sprintf(lbuf,"------------%s已上线-----------",name[i]);for(int j=4;j<1024;j++){send(fds[j].fd,lbuf,sizeof(lbuf),0);}continue;}if(strcmp(rbuf,"quit")==0){sprintf(lbuf,"[%s:%d]%s已下线",inet_ntoa(newsin[i].sin_addr),ntohs(newsin[i].sin_port),name[i]);close(fds[i].fd);newsin[i].sin_addr.s_addr=0;newsin[i].sin_port=0;fds[i].fd=-1;for(int k=4;k<1024;k++){		send(fds[k].fd,lbuf,sizeof(lbuf),0);	}send(fds[0].fd,lbuf,sizeof(lbuf),0);continue;}bzero(lbuf,sizeof(lbuf));char *p=rbuf;p=p+1;strcpy(lbuf,p);sprintf(wbuf,"[%s:%d]%s:%s",inet_ntoa(newsin[i].sin_addr),ntohs(newsin[i].sin_port),name[i],lbuf);for(int j=4;j<1024;j++){if(j==i){continue;}send(fds[j].fd,wbuf,sizeof(wbuf),0);}}}}close(sfd);return 0;
}

客户端

#include <myhead.h>
#define SERIP "192.168.125.99"
#define SERPORT 9999int main(int argc, const char *argv[])
{int cfd=-1;if((cfd=socket(AF_INET,SOCK_STREAM,0))==-1){perror("socket error");return -1;}printf("cfd=%d\n",cfd);int reuse=1;if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt error");return -1;}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SERPORT);sin.sin_addr.s_addr=inet_addr(SERIP);if((connect(cfd,(struct sockaddr*)&sin,sizeof(sin)))==-1){perror("connect error");return -1;}printf("connect success\n");struct pollfd fds[2];fds[0].fd=0;fds[0].events=POLLIN;fds[1].fd=cfd;fds[1].events=POLLIN;int flag=0;char rbuf[128]="";char buf[128]="";char n[129]="N";char s[129]="S";char q[129]="quit";int res=-1;while(1){res=poll(fds,2,-1);if(res<0){perror("poll error");return -1;}else if(res==0){printf("time out\n");return -1;}if(fds[0].revents==POLLIN){if(flag==0){//输入名字bzero(buf,sizeof(buf));bzero(rbuf,sizeof(rbuf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;strcat(rbuf,n);strcat(rbuf,buf);send(cfd,rbuf,sizeof(rbuf),0);flag=1;}else{//输入信息bzero(buf,sizeof(buf));bzero(rbuf,sizeof(rbuf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;if(strcmp(q,buf)==0){send(cfd,buf,sizeof(buf),0);goto END;}strcat(rbuf,s);strcat(rbuf,buf);send(cfd,rbuf,sizeof(rbuf),0);}}if(fds[1].revents==POLLIN){bzero(rbuf,sizeof(rbuf));recv(cfd,rbuf,sizeof(rbuf),0);printf("%s\n",rbuf);}}
END:close(cfd);return 0;
}


http://www.ppmy.cn/news/1279144.html

相关文章

内部FLASH模拟EPPROM

本例程基于STM32F103ZET6 FLASH大小为512K。 介绍FLASH 不同型号的 STM32&#xff0c;其 FLASH 容量也有所不同&#xff0c;最小的只有 16K 字节&#xff0c;最大的则达到了 1024K 字节。我们的精英 STM32 开发板选择的是 STM32F103ZET6 的 FLASH 容量为 512K 字节&#xff0…

计算机网络 网络安全技术

网络安全基本要素 机密性 不泄密完整性 信息不会被破坏可用性 授权用户 正常有效使用可控性 被控制可审查性 网络安全的结构层次 物理安全 物理介质安全控制 计算机操作系统安全服务 应用层次 被动攻击 :截获信息 主动攻击 : 中断信息,篡改,伪造 篡改 …

conda环境下执行conda命令提示无法识别解决方案

1 问题描述 win10环境命令行执行conda命令&#xff0c;报命令无法识别&#xff0c;错误信息如下&#xff1a; PS D:\code\cv> conda activate pt conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&a…

2023年12月GESP Python五级编程题真题解析

【五级编程题1】 【试题名称】&#xff1a;小杨的幸运数 【问题描述】 小杨认为&#xff0c;所有大于等于a的完全平方数都是他的超级幸运数。 小杨还认为&#xff0c;所有超级幸运数的倍数都是他的幸运数。自然地&#xff0c;小杨的所有超级幸运数也都是幸运数。 对于一个…

Jenkins 构建触发器指南

目录 触发远程构建 (例如&#xff0c;使用脚本) 描述 配置步骤 安全令牌 在其他项目构建完成后触发构建 描述 配置步骤 定时触发构建 描述 配置步骤 GitHub钩子触发GITScm轮询 描述 配置步骤 Poll SCM - 轮询版本控制系统 描述 触发远程构建 (例如&#xff0c;使…

数据分析基础之《numpy(5)—合并与分割》

了解即可&#xff0c;用panads 一、作用 实现数据的切分和合并&#xff0c;将数据进行切分合并处理 二、合并 1、numpy.hstack 水平拼接 # hstack 水平拼接 a np.array((1,2,3)) b np.array((2,3,4)) np.hstack((a, b))a np.array([[1], [2], [3]]) b np.array([[2], […

电机控制 相关基础概念

基本概念: 定子或者转子上有铁心或者绕铜线的地方,绕铜线的地方叫槽,而将槽分开的叫齿,将所有的齿连起来的部位较轭部。 磁感应强度与磁场强度之间的关系可以通过以下公式表示: B=μH 其中,B 是磁感应强度,H 是磁场强度,μ 是磁导率。这个关系表明,在给定磁场强度下…

分而治之:Fork/Join框架(构造一个1到200 000求和的任务)

Fork一词的原始含义是吃饭用的叉子&#xff0c;也有分叉的意思。在linux平台中&#xff0c; 方法fork用来创建子进程。使得系统进程可以多一个执行分组。 而join方法这里表示等待&#xff0c;也就是使用fork方法后系统多了一个执行分支(线程) 所以需要等待这个执行分支执行完毕…