[关闭]
@expl0r3r 2018-06-26T13:03:45.000000Z 字数 3598 阅读 199

Server_UDP.c

ChatRoom


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h>
  10. #include <signal.h>
  11. #define N 128
  12. #define L 1
  13. #define B 2
  14. #define Q 3
  15. //message structrue
  16. typedef struct{
  17. char type;
  18. char name[32];
  19. char text[N];
  20. }MSG;
  21. //linklist to save socket addresses
  22. typedef struct node{
  23. struct sockaddr_in addr;
  24. struct node *next;
  25. }listnode,*linklist;
  26. //some variables and structures
  27. int socketfd;
  28. socklen_t addr_len;
  29. pid_t pid;
  30. MSG msg;
  31. struct sockaddr_in server_addr,client_addr;
  32. //create the head of linklist
  33. linklist linklist_create(){
  34. linklist H;
  35. H = (linklist)malloc(sizeof(listnode)); //apply room from system
  36. memset(H,0,sizeof(listnode)); //set value for the room that H point
  37. H -> next = NULL; //set "next" as dangling pointer
  38. return H;
  39. }
  40. //insert data into linklist
  41. void insert_data(linklist H,struct sockaddr_in client_addr){
  42. linklist p = NULL;
  43. p = (linklist)malloc(sizeof(listnode));
  44. p -> addr = client_addr;
  45. p -> next = H -> next;
  46. H -> next = p;
  47. return ;
  48. }
  49. //the process for users to login
  50. void process_login(int socketfd,linklist H,MSG msg,struct sockaddr_in client_addr){
  51. insert_data(H,client_addr);
  52. linklist h1 = H;
  53. while(h1 -> next != NULL){
  54. h1 = h1 -> next;
  55. if(memcmp(&client_addr,&h1 -> addr,sizeof(client_addr)) != 0){
  56. if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&(h1 -> addr),sizeof(h1 -> addr)) < 0){
  57. perror("sendto failed4");
  58. exit(-1);
  59. }
  60. }
  61. }
  62. return ;
  63. }
  64. //the process broadcasting messages to each user
  65. void process_broadcast(int socketfd,linklist H,MSG msg,struct sockaddr_in client_addr){
  66. linklist h1 = H;
  67. while(h1 -> next != NULL){
  68. h1 = h1 -> next;
  69. if(memcmp(&client_addr,&h1->addr,sizeof(client_addr)) != 0){
  70. if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&(h1 -> addr),sizeof(h1 -> addr)) < 0){
  71. perror("sendto failed3");
  72. exit(-1);
  73. }
  74. }
  75. }
  76. return ;
  77. }
  78. //the process run if a user quits
  79. void process_quit(int socketfd,linklist H,MSG msg,struct sockaddr_in client_addr){
  80. linklist p = H;
  81. linklist q;
  82. while(p -> next){
  83. if(memcmp(&client_addr,&p -> next -> addr,sizeof(client_addr)) == 0){
  84. q = p -> next;
  85. p -> next = q -> next;
  86. free(q);
  87. q = NULL;
  88. }
  89. else{
  90. if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->next->addr,sizeof(p->next->addr)) < 0){
  91. perror("sendto failed2");
  92. exit(-1);
  93. }
  94. p = p -> next;
  95. }
  96. }
  97. return ;
  98. }
  99. //fork function runs once will return two result,the one is 0(means parent process),the other is the ip of the child process
  100. void start(){
  101. linklist H = linklist_create();
  102. if ((pid = fork()) == -1){
  103. perror("fork failed");
  104. exit(-1);
  105. }
  106. if (pid == 0){
  107. while(1){
  108. fgets(msg.text,N,stdin);
  109. msg.text[strlen(msg.text)-1] = '\0';
  110. strcpy(msg.name,"server");
  111. msg.type = 'B';
  112. if (sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0){
  113. perror("sendto failed1");
  114. close(socketfd);
  115. exit(-1);
  116. }
  117. }
  118. }
  119. if(pid > 0){
  120. while(1){
  121. if (recvfrom(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&client_addr,&addr_len) < 0){
  122. perror("recvfrom");
  123. close(socketfd);
  124. exit(-1);
  125. }
  126. switch(msg.type){
  127. case 'L':
  128. process_login(socketfd,H,msg,client_addr);
  129. break;
  130. case 'B':
  131. process_broadcast(socketfd,H,msg,client_addr);
  132. break;
  133. case 'Q':
  134. process_quit(socketfd,H,msg,client_addr);
  135. break;
  136. }
  137. }
  138. }
  139. }
  140. //the initialize function,'argc' means the number of the arrays 'argv','argv[0]' means the path of this file
  141. //'argv[1]' and 'argv[2]' mean the two parameters you pass in,the first one is ip,the second one is port
  142. void init(int argc,char *argv[]){
  143. if (argc < 3){
  144. printf("usage: %s ip port\n",argv[0]);
  145. exit(-1);
  146. }
  147. memset(&server_addr,0,sizeof(server_addr));
  148. server_addr.sin_family = AF_INET;
  149. server_addr.sin_addr.s_addr = inet_addr(argv[1]);
  150. server_addr.sin_port = htons(atoi(argv[2]));
  151. if((socketfd = socket(PF_INET,SOCK_DGRAM,0)) < 0){
  152. perror("socket failed");
  153. exit(-1);
  154. }
  155. if(bind(socketfd,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0){
  156. perror("bind failed");
  157. exit(-1);
  158. }
  159. addr_len = sizeof(client_addr);
  160. }
  161. //main function
  162. int main(int argc,char *argv[]){
  163. init(argc,argv);
  164. start();
  165. return 0;
  166. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注