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

8.19作业

1.项目:建立服务器和客户端(客户端发出的信息其他客户端接收,服务器发出的信息全部客户端接收)

服务器代码:

#include <25061head.h>#define SER_IP "192.168.109.126"
#define SER_PORT 8888typedef struct Node
{union{int data;int len;};char username[50];struct sockaddr_in addr;struct Node *next;
}*linklist;linklist creat_head()
{linklist head=(linklist)malloc(sizeof(struct Node));if(head==NULL){return NULL;}head->len=0;head->next=NULL;return head;
}linklist creat_node(int fd,const char* name,struct sockaddr_in addr)
{linklist s=(linklist)malloc(sizeof(struct Node));if(NULL==s){return NULL;}s->data=fd;strncpy(s->username,name,sizeof(s->username)-1);s->username[sizeof(s->username)-1]='\0';s->next=NULL;return s;
}int insert_rear(int fd,const char* name,struct sockaddr_in addr,linklist head)
{if(NULL==head){return -1;}linklist s=creat_node(fd,name,addr);if(NULL==s){return -1;}linklist p=head;while(p->next!=NULL){p=p->next;}p->next=s;head->len++;return 0;
}int delete_client(linklist head,int fd)
{if(NULL==head||NULL==head->next){return -1;}linklist prev=head;linklist curr=head->next;while(curr!=NULL){if(curr->data==fd){prev->next=curr->next;free(curr);head->len--;return 0;}prev=curr;curr=curr->next;}return -1;
}const char *find_username(linklist head,int fd)
{linklist p=head->next;while(p!=NULL){if(p->data==fd){return p->username;}p=p->next;}return "unknown";
}void broadcast(linklist head,char *msg,int exclude_fd)
{linklist p=head->next;while(p!=NULL){if(p->data!=exclude_fd){send(p->data,msg,strlen(msg),0);}p=p->next;}
}int main(int argc, const char *argv[])
{linklist head=creat_head();if(head==NULL){perror("creat_head error");return -1;}int sfd=socket(AF_INET,SOCK_STREAM,0);if(-1==sfd){perror("socket error");return -1;}printf("socket success sfd=%d\n",sfd);int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\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);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");struct sockaddr_in cin;socklen_t addrlen=sizeof(cin);char buf[256]="";fd_set readsfds;FD_ZERO(&readsfds);FD_SET(0,&readsfds);FD_SET(sfd,&readsfds);fd_set tempfds;int maxfd=sfd;while(1){tempfds=readsfds;int res=select(maxfd+1,&tempfds,NULL,NULL,NULL);if(res==-1){perror("select error");break;}else if(res==0){printf("time out\n");continue;}if(FD_ISSET(sfd,&tempfds)){int new_fd=accept(sfd,(struct sockaddr*)&cin,&addrlen);if(-1==new_fd){perror("accept error");continue;}char username_buf[50]={0};ssize_t name_len=recv(new_fd,username_buf,sizeof(username_buf),0);if(name_len<=0){perror("recv name error");close(new_fd);continue;}username_buf[name_len]='\0';if(insert_rear(new_fd,username_buf,cin,head)==0){printf("新客户端:%s(fd=%d)\n",username_buf,new_fd);char join_msg[256];snprintf(join_msg,sizeof(join_msg),"[系统]%s登录",username_buf);broadcast(head,join_msg,-1);}FD_SET(new_fd,&readsfds);if(new_fd>maxfd){maxfd=new_fd;}printf("[%s:%d] fd=%d username=%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),new_fd,username_buf);}//服务器向客户端发送信息if(FD_ISSET(0,&tempfds)){if(fgets(buf,sizeof(buf),stdin)==NULL){perror("fgets error");continue;}if(strlen(buf)==0){continue;}char system_msg[2048];snprintf(system_msg,sizeof(system_msg),"[系统公告]:%s",buf);broadcast(head,system_msg,-1);}for(int i=sfd+1;i<=maxfd;i++){if(FD_ISSET(i,&tempfds)){char rbuf[128]="";ssize_t res=recv(i,rbuf,sizeof(rbuf)-1,0);if(res==0){const char *username=find_username(head,i);printf("客户端%s(fd=%d)已下线\n",username,i);char leave[256];snprintf(leave,sizeof(leave),"[系统]:%s下线",username);broadcast(head,leave,i);close(i);FD_CLR(i,&readsfds);delete_client(head,i);if(i=maxfd){for(int j=maxfd-1;j>=sfd;j--){if(FD_ISSET(j,&readsfds)){maxfd=j;break;}}}continue;}if(res==-1){perror("recv error");close(i);FD_CLR(i,&readsfds);delete_client(head,i);continue;}rbuf[res]='\0';const char *sender_name=find_username(head,i);char fullmsg[512];snprintf(fullmsg,sizeof(fullmsg),"[%s]:%s",sender_name,rbuf);broadcast(head,fullmsg,i);}}}close(sfd);linklist curr=head->next;while(curr!=NULL){linklist next=curr->next;close(curr->data);free(curr);curr=next;}free(head);return 0;
}

客户端代码:

#include <25061head.h>#define SER_PORT 8888
#define SER_IP "192.168.109.126"int cfd;void *callback(void* arg)
{char buf[256];while(1){ssize_t res=recv(cfd,buf,sizeof(buf)-1,0);if(res<=0){printf("与服务器断开连接\n");close(cfd);exit(0);}buf[res]='\0';printf("%s\n",buf);fflush(stdout);}return NULL;
}int main(int argc, const char *argv[])
{if(argc!=4){printf("%s[用户名][服务器IP][端口号]\n",argv[0]);return -1;}const char *username=argv[1];const char *system_ip=argv[2];int port=atoi(argv[3]);cfd=socket(AF_INET,SOCK_STREAM,0);if(-1==cfd){perror("socket error");return -1;}printf("socket success cfd=%d\n",cfd);struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(port);sin.sin_addr.s_addr=inet_addr(system_ip);if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("connect error");return -1;}printf("连接成功\n");send(cfd,username,strlen(username),0);pthread_t thread=-1;if(pthread_create(&thread,NULL,callback,NULL)!=0){printf("线程创建失败\n");close(cfd);return -1;}pthread_detach(thread);char buf[256];while(1){if(fgets(buf,sizeof(buf),stdin)==NULL){break;}if(strcmp(buf,"quit")==0){break;}send(cfd,buf,strlen(buf),0);}close(cfd);return 0;
}

结果:

2.

http://www.xdnf.cn/news/1325701.html

相关文章:

  • 星图云开发者平台新功能速递 | 微服务管理器:无缝整合异构服务,释放云原生开发潜能
  • 部署tomcat应用时注意事项
  • 数据迁移:如何从MySQL数据库高效迁移到Neo4j图形数据库
  • 高性能AI推理与工作站GPU:DigitalOcean L40s、RTX 6000 Ada与A6000全解析
  • UniApp 微信小程序之间跳转指南
  • Leetcode 343. 整数拆分 动态规划
  • 【最新版】CRMEB Pro版v3.4系统源码全开源+PC端+uniapp前端+搭建教程
  • LLM 中 token 简介与 bert 实操解读
  • 大语言模型中的归一化实现解析
  • Vim笔记:缩进
  • AiPPT怎么样?好用吗?
  • Qt密码生成器项目开发教程 - 安全可靠的随机密码生成工具
  • Orbbec---setBoolProperty 快捷配置设备行为
  • Go高效复用对象:sync.Pool详解
  • JavaScript 性能优化:new Map vs Array.find() 查找速度深度对比
  • openldap安装 -添加条目
  • 【什么是非晶合金?非晶电机有什么优点?】
  • RecSys:粗排模型和精排特征体系
  • 图解快速排序C语言实现
  • “道法术器” 思维:解析华为数字化转型
  • Lua学习记录 - 自定义模块管理器
  • 数据库:表和索引结构
  • 如何新建一个自己的虚拟环境
  • 实践笔记-小端模式下的寄存器数据输入技巧;图形化界面配置注意事项。
  • AI应用商业化加速落地 2025智能体爆发与端侧创新成增长引擎
  • 安装pnpm i -D @types/wechat-miniprogram报错,版本不匹配
  • 继承——Java中的“家族传承”
  • JavaSE高级-02
  • Read Frog:一款开源AI浏览器语言学习扩展
  • 网络基础——协议认识