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

23062网络编程day7

网络聊天室编写(基于UDP)

服务器

#include <myhead.h>#define PORT 8888               //端口号:接收方绑定的端口号
#define IP "192.168.114.56"    //本机IP#define ERR_MSG(msg)  do{\fprintf(stderr, "__%d__:", __LINE__); \perror(msg);\
}while(0)//需要传入到分支线程的参数
typedef struct Climsg{char code;char user[32];char text[128];
}msg_t;//创建链表存储数据
typedef struct Node{struct sockaddr_in addr; struct Node *next;
}node_t,*nodeptr; //创建节点的函数
int create_node(nodeptr *phead){*phead = (nodeptr)malloc(sizeof(node_t));if(NULL == *phead){printf("内存分配失败\n");exit(-1);}(*phead)->next=NULL;return 0;
}
//尾插法
int insert_data_by_tail(node_t *phead,struct sockaddr_in addr){if(NULL == phead){printf("参数为NULL,请检查\n");return -1;}//将新客户端使用尾插法插入链表中nodeptr pnew = NULL;create_node(&pnew);pnew->addr = addr;  nodeptr ptemp =phead;while(ptemp->next != NULL){ptemp = ptemp->next;}//让尾结点的指针域指向新节点ptemp->next = pnew;return 0;
}int main(int argc, const char *argv[])
{int sfd = 0;if(-1==(sfd=socket(AF_INET,SOCK_DGRAM,0))){ERR_MSG("socket error");}struct sockaddr_in sin;memset(&sin,0,sizeof(sin));sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);socklen_t sin_len = sizeof(sin);if(-1 == bind(sfd,(struct sockaddr *)&sin,sin_len)){ERR_MSG("bind error");} struct sockaddr_in cin,temp_cin;memset(&cin,0,sizeof(cin));socklen_t cin_len = sizeof(cin);char name[32] = {0};pid_t pid = 0;msg_t msg;msg_t msg_send;//创建头结点nodeptr phead;create_node(&phead);phead->addr = cin;if(-1 == (pid = fork())){ERR_MSG("fork error");}else if(0 == pid){   //子进程 接收数据 (1、d 登录操作 2、q 群聊操作 3、t 退出操作)  while(1){memset(&msg,0,sizeof(msg));if(-1 == recvfrom(sfd, (void*)&msg, sizeof(msg),0, (struct sockaddr *)&cin,&cin_len)){perror("recv error");}    switch(msg.code){case 'd':printf("用户[%s]上线\n", msg.user);              insert_data_by_tail(phead,cin);nodeptr q=phead->next;                while(q != NULL){msg.code='d';if(-1 == sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr *)&q->addr,sizeof(q->addr))){ERR_MSG("send error");}q=q->next;}break; case 'q':                     if(strcmp("系统提示",msg.user)!=0){printf("[%s]:%s\n",msg.user, msg.text);}node_t *p = phead->next;                while(p != NULL){msg.code='q';if(-1 == sendto(sfd,(void *)&msg,sizeof(msg),0,(struct sockaddr *)&p->addr,sizeof(p->addr))){ERR_MSG("send error");}p=p->next;}                break; case 't':    printf("用户[%s]:已退出\n", msg.user);nodeptr t = phead; nodeptr pdel = NULL;               while(t->next != NULL){msg.code='t';if( 0 == memcmp(&(t->next->addr), &cin,sizeof(cin))){pdel = t->next;t->next = pdel->next;free(pdel);}else{t = t->next;if(-1 == sendto(sfd, &msg,sizeof(msg),0,(struct sockaddr *)&t->addr,sizeof(t->addr))){ERR_MSG("send error");}}    }     break;}}}else if(0 < pid){//父进程 发送系统消息while(1){  strcpy(msg_send.user,"系统");memset(msg_send.text,0,128);fgets(msg_send.text,128,stdin);msg_send.text[strlen(msg_send.text)-1] = '\0';msg_send.code = 'q';              if(-1 == sendto(sfd,&msg_send,sizeof(msg_send),0,(struct sockaddr *)&sin,sin_len)){ERR_MSG("send error");                }               }} kill(pid, SIGKILL);wait(NULL);//给子进程回收资源exit(0);     close(sfd);return 0;
}

客户端

#include <myhead.h>#define PORT 8888               //端口号:接收方绑定的端口号#define ERR_MSG(msg)  do{\fprintf(stderr, "__%d__:", __LINE__); \perror(msg);\
}while(0)
#define IP  "192.168.114.56"    //本机IP,ifconfig
#define M 32
#define N 128
typedef struct _Node{struct sockaddr_in addr;struct _Node *next;
}node_t;typedef struct _Msg{char code;char user[M];char text[N];
}msg_t;int main(int argc, const char *argv[])
{//创建用户数据报套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){ERR_MSG("socket error");}//填充服务器网络信息结构体struct sockaddr_in sin;memset(&sin, 0, sizeof(sin));sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);socklen_t sin_len = sizeof(sin);int res = 0;char name[32]={0};msg_t msg;pid_t pid;struct sockaddr_in cin;memset(&cin,0,sizeof(cin));socklen_t cin_len = sizeof(cin);//输入用户名,完成登陆操作printf("请输入登录信息:");msg.code = 'd';memset(msg.user, 0, 32);fgets(name, 32, stdin);//在终端获取用户名strcpy(msg.user,name);msg.user[strlen(msg.user) - 1] = '\0';if (-1 == sendto(sockfd,&msg,sizeof(msg),0, (struct sockaddr *)&sin,sin_len)){  //给服务器发送用户名ERR_MSG("send error");}//创建进程if(-1 == (pid = fork())){ERR_MSG("fork error");}else if(0 == pid){   //子进程 接收数据  while (1){memset(&msg,0,sizeof(msg));//接收服务器的应答if (-1 == (res=recvfrom(sockfd, &msg, sizeof(msg), 0,(struct sockaddr *)&sin,&sin_len))){ERR_MSG("recv error");}                         if(strcmp(msg.user,name) == -10){               continue;}else{//打印应答信息switch(msg.code){case 'd':printf("用户[%s]登录上线了....\n", msg.user); break; case 'q':printf("[%s]:%s\n",msg.user,msg.text);break;case 't':            printf("用户[%s]已退出\n", msg.user); break;}  } }    }else if(0 < pid){//父进程 发送数据(2、q:群聊操作  3、t:退出操作)while(1){//在终端获取群聊memset(msg.text, 0, 128);fgets(msg.text, 128, stdin);msg.text[strlen(msg.text) - 1] = '\0'; //清空结尾的 '\n'               if( 0 ==strcmp(msg.text, "quit")){msg.code = 't'; if (-1 == sendto(sockfd, &msg, sizeof(msg), 0,(struct sockaddr *)&sin,sin_len)){ERR_MSG("send error");     }   break;}else{msg.code = 'q';    }//给服务器发送群聊消息if (-1 == sendto(sockfd, &msg, sizeof(msg), 0,(struct sockaddr *)&sin,sin_len)){ERR_MSG("send error");}}     }      //关闭套接字close(sockfd);return 0;
}

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

相关文章:

  • Java面向对象学习笔记-2
  • 入栏需看——学习记忆
  • [C++]杨辉三角
  • 算法通关村十三关-白银:数字与数学高频问题
  • 【Linux】线程安全-互斥同步
  • 1.初识爬虫
  • TLA+学习记录1——hello world
  • 基于QWebEngine实现无头浏览器
  • 编译Micropython固件For树莓派Raspberry Pi Pico
  • 基于googlenet网络的动物种类识别算法matlab仿真
  • 如何用Jmeter编写脚本压测?
  • SpingMVC之拦截器使用详解
  • motionface respeak新的aigc视频与音频对口型数字人
  • 【计算机网络】 静态库与动态库
  • web端调用本地摄像头麦克风+WebRTC腾讯云,实现直播功能
  • React笔记(八)Redux
  • 数据库 | 数据库概述、关系型数据库、非关系型数据库
  • 【备战csp-j】 csp常考题目详解(4)
  • linux中常见服务端安装
  • L1-058 6翻了(Python实现) 测试点全过
  • 初学Python记
  • 计算机竞赛 基于深度学习的目标检测算法
  • sentinel-core
  • 【美团3.18校招真题1】
  • Springboot 实践(14)spring config 配置与运用--手动刷新
  • MyBatisPlus枚举类最佳实践(非常典型和高效的枚举类写法)
  • uniapp分包 解决分多个包的问题
  • 美国封锁激励中国制造业数字化转型的崛起 | 百能云芯
  • 鼠标键盘自动化工具pyautogui
  • 0基础学习VR全景平台篇 第96篇:VR电子楼书