服务器与客户端简单通信——server

xiaoxiao2021-02-28  89

#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <strings.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #define SERV_PORT 9000 #define BUFF_SIZE 1024 struct user { int socketfd; char name[20]; char toName[20]; int result;  // 0 代表失败 1代表成功 2 代表别人给你发的信息 3代表没注册 4错误的指令 char msg[100]; int cmd;  // 5 代表注册用户  10 // 代表发送信息 }; struct userManage { int flag[20];   // 表明哪个空缺  struct user users[20]; }; pthread_mutex_t mutex; struct userManage uMge;  void save_user(int socket_fd, struct user * userInfo) { pthread_mutex_lock(&mutex); int i = 0; for (i = 0; i < 20; i++) { if (uMge.flag[i] == 1) { continue; } uMge.users[i].socketfd = socket_fd; strcpy(uMge.users[i].name, userInfo->name); userInfo->result = 1; uMge.flag[i] = 1; printf ("%s register success!\n", uMge.users[i].name); break; } pthread_mutex_unlock(&mutex); } int server_request(int cfd) { int readSize, writeSize; int ret = 0; int i; struct user userInfo; int toname_fd = -1; int isRegister = -1; while (readSize = read(cfd, &userInfo, sizeof(userInfo))) { if (readSize == -1) { perror("read"); return -1; } if (userInfo.cmd == 5)             // 注册用户 { save_user(cfd, &userInfo);     // 将用户信息进行保存 } else if (userInfo.cmd == 10)  // 发送信息 { // 检测该用户是否注册 for (i = 0; i < 20; i++) { if (uMge.flag[i] == 1) { if (uMge.users[i].socketfd == cfd) { if (strcmp(uMge.users[i].name, userInfo.name) == 0) { isRegister = 1; } } } } if(isRegister == 1) { // 寻找要发送的用户 for (i = 0; i < 20; i++) { if (uMge.flag[i] == 1) { // 找到了要发送的用户,将其socket保存起来 if (strcmp(uMge.users[i].name, userInfo.toName) == 0) { toname_fd = uMge.users[i].socketfd; } } } if(toname_fd != -1)  // 没找到要发送的用户 { userInfo.result = 2;   // 找到用户将其返回状态标为1  writeSize = write(toname_fd, &userInfo, sizeof(userInfo)); if (writeSize == -1) { perror("write"); return -1; } printf ("%s send msg to %s : %s\n", userInfo.name, userInfo.toName, userInfo.msg); userInfo.result = 1;  // 发送成功 } } else { userInfo.result = 3;  // 没有注册 } } else { userInfo.result = 4;  // 错误的指令 } writeSize = write(cfd, &userInfo, sizeof(userInfo)); if (writeSize == -1) { perror("write"); return -1; } memset(userInfo.msg, 0, sizeof(userInfo.msg)); } } int main() { int listen_sockfd; int ret; struct sockaddr_in server_addr;  // 服务器地址结构 struct sockaddr_in client_addr;  // 客户端的地址 pthread_mutex_init(&mutex, NULL); // 创建监听套接字 listen_sockfd = socket(AF_INET, SOCK_STREAM, 0); if (listen_sockfd == -1) { perror("create socket error"); return -1; } // 初始化服务器地址结构 bzero(&server_addr, sizeof(server_addr));          // 将地址结构变量清零   server_addr.sin_family = AF_INET;                  // 选择IPV4地址 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);   // 监听本地任意IP地址 server_addr.sin_port = htons(SERV_PORT);           // 将本地端口号转化为网络端口号 // 绑定本地地址和端口号 ret = bind(listen_sockfd, (struct sockaddr *)&server_addr, sizeof (server_addr)); if (ret == -1) { perror ("bind error"); return -1; } // 监听套接字 ret = listen(listen_sockfd, 20); if (ret == -1) { perror("listen error"); return -1; } while(1) { int clientfd; socklen_t client_len = sizeof(client_addr); clientfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &client_len); if (clientfd == -1) { perror("accept error"); return -1; } pthread_t tid; // 创建线程处理客户端请求 int ret = pthread_create(&tid, NULL, server_request, (void *)clientfd); if (ret != 0) { printf ("create pthread error!\n"); return -1; } pthread_detach(tid); // 线程分离 } pthread_mutex_destroy(&mutex); return 0; }
转载请注明原文地址: https://www.6miu.com/read-28764.html

最新回复(0)