落地页需要建网站吗,seo推广宣传,wordpress百万数据库,设计类专业笔记本电脑推荐排行基于UDP的网络聊天室
一.项目需求#xff1a;
1.如果有用户登录#xff0c;其他用户可以收到这个人的登录信息
2.如果有人发送信息#xff0c;其他用户可以收到这个人的群聊信息
3.如果有人下线#xff0c;其他用户可以收到这个人的下线信息
4.服务器可以发送系统信息…基于UDP的网络聊天室
一.项目需求
1.如果有用户登录其他用户可以收到这个人的登录信息
2.如果有人发送信息其他用户可以收到这个人的群聊信息
3.如果有人下线其他用户可以收到这个人的下线信息
4.服务器可以发送系统信息 二.代码
udp.h
#ifndef UDP_H
#define UDP_H
#include myhead.h
#define SER_PORT 8888 // 服务器端口号
#define SER_IP 192.168.0.105 // 服务器ip地址
#define CLI_PORT 5555 // 客户端端口号
#define CLI_IP 192.168.0.105 // 客户端地址
//枚举
enum type_t
{Login,Chat,Quit,
};
typedef struct MSG
{char type;//Login名字 Chat内容 Quit退出 //内容编号char name[32];//名字char text[128];//内容
}msg_t;
typedef struct NODE//链表
{struct sockaddr_in cin;struct NODE *next;
}Node,*Nodeptr;
//创建头节点函数
Nodeptr create();
//登录的函数
//功能
//1.将新登录的用户转发给所有已经登录的用户遍历链表发送谁登录的消息
//2.创建新节点来保存新登录用户的信息链接到链表尾就可以
void do_login(int sockfd,msg_t msg,Nodeptr p,struct sockaddr_in cin);
//群聊的函数
//功能将客户端发来的聊天内容转发给所有已登录的用户除了发送聊天内容的用户以外
void do_chat(int sockfd,msg_t msg,Nodeptr p,struct sockaddr_in cin);
//退出函数
//功能
//1.将谁退出的消息转发给i所有用户
//2.将链表中保存这个推出的用户信息的节点删除
void do_quit(int sockfd,msg_t msg,Nodeptr p,struct sockaddr_in cin);
#endif udp.c
#include udp.h
// 定义创建头节点函数
Nodeptr create()
{Nodeptr p (Nodeptr)malloc(sizeof(Node));if (p NULL){perror(malloc error);return NULL;}p-next NULL;return p;
}
// 定义登录的函数
void do_login(int sockfd, msg_t msg, Nodeptr p, struct sockaddr_in cin)
{sprintf(msg.text, %s 以上线, msg.name);while (p-next ! NULL){p p-next;sendto(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)(p-cin), sizeof(p-cin));}Nodeptr new (Nodeptr)malloc(sizeof(Node));// 初始化new-cin cin;new-next NULL;// 链接到链表尾p-next new;return;
}
// 定义群聊的函数
void do_chat(int sockfd, msg_t msg, Nodeptr p, struct sockaddr_in cin)
{// 遍历链表while (p-next ! NULL){p p-next;if (memcmp((p-cin), cin,sizeof(cin))! 0){sendto(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)(p-cin), sizeof(p-cin));}}return;
}
// 定义退出函数
void do_quit(int sockfd, msg_t msg, Nodeptr p, struct sockaddr_in cin)
{sprintf(msg.text, %s 以下线, msg.name);while (p-next ! NULL){if (memcmp((p-cin), cin,sizeof(cin)) 0){Nodeptr q NULL;q p-next;p-next q-next;free(q);q NULL;}else{p p-next;sendto(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)(p-cin), sizeof(p-cin));}}return;
}
sen.c
// 服务器
#include udp.h
int main(int argc, char const *argv[])
{// 创建UDP套接字int sockfd socket(AF_INET, SOCK_DGRAM, 0);if (sockfd 0){perror(socket error);exit(-1);} // 填充服务器网络信息结构体//定义服务器结构体 struct sockaddr_in sin;sin.sin_familyAF_INET;sin.sin_port htons(SER_PORT);sin.sin_addr.s_addr inet_addr(SER_IP);// 定义保存客户端网络信息的结构体struct sockaddr_in cin;cin.sin_family AF_INET;cin.sin_port htons(CLI_PORT);cin.sin_addr.s_addr inet_addr(CLI_IP);socklen_t len sizeof(cin);// 绑定套接字和服务器网络信息的结构体bind(sockfd, (struct sockaddr *)sin, sizeof(sin));printf(绑定成功!\n);msg_t msg;Nodeptr p create();char s[20];while (1){if (recvfrom(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)cin, len) 0){perror(recvfrom error);return -1;}if (msg.type Login){strcpy(msg.text, 以上线);printf(ip:%s pord:%d name:%s\n, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), msg.name);printf(状态:%s\n, msg.text);//调用登录函数do_login(sockfd, msg, p, cin);}else if (msg.type Chat){//调用群聊函数do_chat(sockfd, msg, p, cin);}else if (msg.type Quit){strcpy(msg.text, 以下线);printf(ip:%s pord:%d name:%s\n, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), msg.name);printf(状态:%s\n, msg.text);//调用退出函数do_quit(sockfd, msg, p, cin);}}close(sockfd);return 0;
}
rec.c
// 客户端
#include udp.h
int main(int argc, char const *argv[])
{int sockfd socket(AF_INET, SOCK_DGRAM, 0);if (sockfd 0){perror(socket error);exit(-1);}struct sockaddr_in sin;sin.sin_family AF_INET;sin.sin_port htons(SER_PORT);sin.sin_addr.s_addr inet_addr(SER_IP);socklen_t len sizeof(sin);msg_t msg;// 先执行登录操作printf(请登录:\n);msg.type Login;printf(请输入用户名:);fgets(msg.name, 32, stdin);msg.name[strlen(msg.name) - 1] 0;// 发送登录消息if (sendto(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)sin, len) 0){perror(sendto err);exit(-1);}//创建多进程pid_t pid fork();if (pid 0){perror(fork error);exit(-1);}else if (pid 0){while (1){if (recvfrom(sockfd, msg, sizeof(msg), 0, NULL, NULL) 0){perror(recvfrom error);return -1;}printf([%s]:%s\n, msg.name, msg.text);}}else{while (1){fgets(msg.text, sizeof(msg.text), stdin);msg.text[strlen(msg.text) - 1] 0;if (strcmp(msg.text, quit) 0){msg.type Quit;sendto(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)sin, len);kill(pid, SIGKILL);wait(NULL);exit(EXIT_SUCCESS);}else{msg.type Chat;}// 发送消息sendto(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)sin, len);}}close(sockfd);return 0;
}