学习笔记:UDP实现进程心跳检测

思路:

UDP服务器端:服务器维护一个client链表,当有client连接创建新节点保存客户主机名和地址,并保存心跳时间heart_beat_time。

当客户端发起一次心跳,服务器收到心跳包更新client节点的心跳时间。服务定时去检测client链表里的每个client的心跳时间,如果心跳时间和当前时间的时间差超过一定的时间间隔,就认为该client已经掉线。

UDP客户端:定时发送心跳包。

服务端代码:

 
 
  1. #include <stdio.h>

  2. #include <stdlib.h>

  3. #include <string.h>

  4. #include <sys/types.h>

  5. #include <sys/socket.h>

  6. #include <arpa/inet.h>

  7. #include <unistd.h>

  8. #include <signal.h>

  9. #include <time.h>

  10. #include <sys/timerfd.h>

  11. #include <pthread.h>

  12. #include <sys/epoll.h>

  13. #define UDP_PORT_NUM (8888)

  14. #define CLIENT_LOGIN 100

  15. #define CLIENT_CHAT 200

  16. #define CLIENT_QUIT 300

  17. #define SERVER_CHAT 400

  18. #define SERVER_QUIT 500

  19. #define PRINT_ONLINE 600

  20. #define PRIVATE_CHAT 700

  21. #define HEART_BEAT 800

  22. static int s_epoll_fd = -1;

  23. typedef enum

  24. {

  25. E_CLIENT_OFF_LINE = 0,

  26. E_CLIENT_ON_LINE

  27. }eClientSatus;

  28. struct node

  29. {

  30. char name[20]; // client name

  31. struct sockaddr_in client_addr; // client addr

  32. eClientSatus client_status; // client status

  33. struct timespec heart_beat_time; // each heart beat update this time

  34. struct node *next;

  35. };

  36. struct message

  37. {

  38. long type;

  39. char name[20];

  40. char peer_name[20];

  41. char mtext[512];

  42. };

  43. struct node *create_list(void);

  44. void insert_list(struct node *, char *, struct sockaddr_in *);

  45. void delete_list(struct node *, char *);

  46. void recv_message(int , struct node *);

  47. void send_message(int , struct sockaddr_in *, pid_t );

  48. void client_login(int , struct node *, struct message *, struct sockaddr_in *);

  49. void client_chat(int , struct node *, struct message *);

  50. void client_quit(int , struct node *, struct message *);

  51. void server_chat(int , struct node *, struct message *);

  52. void server_quit(int , struct node *, struct message *);

  53. void brocast_msg(int , struct node *, struct message *);

  54. void print_online(int , struct node *, struct message *);

  55. void private_chat(int , struct node *, struct message *);

  56. void father_func(int sig_no)

  57. {

  58. return ;

  59. }

  60. /* return ms */

  61. static int calcProcessTime(int *pStartMs)

  62. {

  63. struct timespec endTime;

  64. clock_gettime(CLOCK_REALTIME, &endTime);

  65. if(pStartMs){

  66. return endTime.tv_sec * 1000 + endTime.tv_nsec / 1000000 - *pStartMs;

  67. }

  68. return endTime.tv_sec * 1000 + endTime.tv_nsec / 1000000;

  69. }

  70. static void epollAddEvent(int epollFd, int addFd, int state)

  71. {

  72. struct epoll_event ev;

  73. ev.events = state;

  74. ev.data.fd = addFd;

  75. epoll_ctl(epollFd, EPOLL_CTL_ADD, addFd, &ev);

  76. return;

  77. }

  78. void* monitor_thread(void* user)

  79. {

  80. struct node *head = (struct node *)user;

  81. struct epoll_event events[1] = {0};

  82. int cnt = 0;

  83. while(1)

  84. {

  85. int ms = 0;

  86. ms = calcProcessTime(NULL);

  87. int fireEvents = epoll_wait(s_epoll_fd, events, 1, -1);

  88. ms = calcProcessTime(&ms);

  89. if(fireEvents > 0){

  90. printf("monitor time out: %d ms\n", ms);

  91. uint64_t exp;

  92. ssize_t size = read(events[0].data.fd, &exp, sizeof(uint64_t));

  93. if(size != sizeof(uint64_t)) {

  94. printf("read error!\n");

  95. }

  96. struct node *p = head;

  97. struct timespec nowTime;

  98. clock_gettime(CLOCK_REALTIME, &nowTime);

  99. while (p != NULL){

  100. /* if 10 second not receive client heart beat, we think the client is offline */

  101. if(p->client_status == E_CLIENT_ON_LINE) {

  102. int duration = (nowTime.tv_sec * 1000 + nowTime.tv_nsec / 1000000) - (p->heart_beat_time.tv_sec * 1000 + p->heart_beat_time.tv_nsec / 1000000);

  103. if (duration > 10000) {

  104. p->client_status = E_CLIENT_OFF_LINE;

  105. printf("client: %s had off line\n", p->name);

  106. }

  107. }

  108. p = p->next;

  109. }

  110. printf("All client check finished\n");

  111. }

  112. else{

  113. printf("fireEvents = %d", fireEvents);

  114. }

  115. }

  116. }

  117. int main(int argc, const char *argv[])

  118. {

  119. int socket_fd;

  120. pid_t pid;

  121. struct sockaddr_in server_addr;

  122. struct node *head;

  123. if (argc < 2){

  124. fprintf(stderr, "usages : %s ip\n", argv[0]);

  125. exit(-1);

  126. }

  127. /* create UDP socket */

  128. if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){

  129. perror("failed to create socket");

  130. exit(-1);

  131. }

  132. /* create client list */

  133. head = create_list();

  134. server_addr.sin_family = AF_INET;

  135. server_addr.sin_port = htons(UDP_PORT_NUM);

  136. server_addr.sin_addr.s_addr = inet_addr(argv[1]);

  137. if (bind(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){

  138. perror("failed to bind");

  139. exit(-1);

  140. }

  141. if ((pid = fork()) < 0){

  142. perror("failed to fork pid");

  143. exit(-1);

  144. }

  145. if (pid == 0){

  146. /* create epoll */

  147. int epollFd = -1;

  148. epollFd = epoll_create(1);

  149. s_epoll_fd = epollFd;

  150. /* create timer */

  151. int timerFd = -1;

  152. timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);

  153. /* add timer fd to epoll monitor event */

  154. epollAddEvent(epollFd, timerFd, EPOLLIN);

  155. /* create thread to monitor */

  156. pthread_t threadId = -1;

  157. pthread_create(&threadId, NULL, &monitor_thread, (void*)head);

  158. /* create timer, time out is 10 seconds */

  159. struct itimerspec its;

  160. its.it_interval.tv_sec = 10; // 10 seconds

  161. its.it_interval.tv_nsec = 0;

  162. its.it_value.tv_sec = 10;

  163. its.it_value.tv_nsec = 0;

  164. if (timerfd_settime(timerFd, 0, &its, NULL) < 0) {

  165. fprintf(stderr, "timerfd_settime error\n");

  166. }

  167. printf("udp server <receive message> running......\n");

  168. recv_message(socket_fd, head);

  169. }

  170. else{

  171. printf("udp server <send message> running......\n");

  172. send_message(socket_fd, &server_addr, pid);

  173. }

  174. return 0;

  175. }

  176. struct node *create_list(void)

  177. {

  178. struct node *head;

  179. head = (struct node *)malloc(sizeof(struct node));

  180. head->next = NULL;

  181. return head;

  182. }

  183. void insert_list(struct node *head, char *name, struct sockaddr_in *client_addr)

  184. {

  185. if(!head) return;

  186. struct node *new;

  187. new = (struct node *)malloc(sizeof(struct node));

  188. strcpy(new->name, name);

  189. new->client_addr = *client_addr;

  190. new->client_status = E_CLIENT_ON_LINE;

  191. clock_gettime(CLOCK_REALTIME, &new->heart_beat_time);

  192. new->next = head->next;

  193. head->next = new;

  194. return ;

  195. }

  196. void delete_list(struct node *head, char *name)

  197. {

  198. if(!head) return;

  199. struct node *p = head->next;

  200. struct node *q = head;

  201. while (p != NULL){

  202. if (strcmp(p->name, name) == 0)

  203. break;

  204. p = p->next;

  205. q = q->next;

  206. }

  207. q->next = p->next;

  208. p->next = NULL;

  209. free(p);

  210. return ;

  211. }

  212. void recv_message(int socket_fd, struct node *head)

  213. {

  214. struct message msg;

  215. struct sockaddr_in client_addr;

  216. int client_addrlen = sizeof(struct sockaddr);

  217. while (1)

  218. {

  219. memset(&msg, 0, sizeof(msg));

  220. if (recvfrom(socket_fd, &msg, sizeof(msg), 0, (struct sockaddr *)&client_addr, &client_addrlen) < 0){

  221. perror("failed to recvform client");

  222. exit(-1);

  223. }

  224. switch(msg.type)

  225. {

  226. case CLIENT_LOGIN:

  227. client_login(socket_fd, head, &msg, &client_addr);

  228. break;

  229. case CLIENT_CHAT:

  230. client_chat(socket_fd, head, &msg);

  231. break;

  232. case CLIENT_QUIT:

  233. client_quit(socket_fd, head, &msg);

  234. break;

  235. case SERVER_CHAT:

  236. server_chat(socket_fd, head, &msg);

  237. break;

  238. case SERVER_QUIT:

  239. server_quit(socket_fd, head, &msg);

  240. break;

  241. case PRINT_ONLINE:

  242. print_online(socket_fd, head, &msg);

  243. break;

  244. case PRIVATE_CHAT:

  245. private_chat(socket_fd, head, &msg);

  246. break;

  247. case HEART_BEAT:

  248. heart_beat(socket_fd, head, &msg);

  249. break;

  250. default:

  251. break;

  252. }

  253. }

  254. return ;

  255. }

  256. void send_message(int socket_fd, struct sockaddr_in *server_addr, pid_t pid)

  257. {

  258. struct message msg;

  259. char buf[512];

  260. signal(getppid(), father_func);

  261. while (1)

  262. {

  263. usleep(500);

  264. printf(">");

  265. fgets(buf, sizeof(buf), stdin);

  266. buf[strlen(buf) - 1] = 0;

  267. strcpy(msg.mtext, buf);

  268. strcpy(msg.name , "server");

  269. msg.type = SERVER_CHAT;

  270. if (strncmp(buf, "quit", 4) == 0){

  271. msg.type = SERVER_QUIT;

  272. printf("udp server will quit, socket_fd = %d!!!!!\n", socket_fd);

  273. if (sendto(socket_fd, &msg, sizeof(msg), 0,

  274. (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){

  275. perror("failed to send server_quit message");

  276. exit(-1);

  277. }

  278. //pause();

  279. kill(pid, SIGKILL);

  280. waitpid(pid, NULL, 0);

  281. close(socket_fd);

  282. exit(-1);

  283. }

  284. if (sendto(socket_fd, &msg, sizeof(msg), 0, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){

  285. perror("failed to send server_chat message");

  286. exit(-1);

  287. }

  288. }

  289. return ;

  290. }

  291. void client_login(int socket_fd, struct node *head, struct message *msg, struct sockaddr_in *client_addr)

  292. {

  293. printf("********Login In Notice********\n");

  294. printf("%s has Login In, you can talk to him/her.\n", msg->name);

  295. printf("****************************\n");

  296. insert_list(head, msg->name, client_addr);

  297. brocast_msg(socket_fd, head, msg);

  298. return ;

  299. }

  300. void client_chat(int socket_fd, struct node *head, struct message *msg)

  301. {

  302. printf("********Group Chat********\n");

  303. printf("name: %s\n", msg->name);

  304. printf("msg: %s\n", msg->mtext);

  305. printf("**************************\n");

  306. brocast_msg(socket_fd, head, msg);

  307. return ;

  308. }

  309. void client_quit(int socket_fd, struct node *head, struct message *msg)

  310. {

  311. printf("*********Quit Msg********\n");

  312. printf("%s is Quit\n", msg->name);

  313. printf("*************************\n");

  314. delete_list(head, msg->name);

  315. brocast_msg(socket_fd, head, msg);

  316. return ;

  317. }

  318. void server_chat(int socket_fd, struct node *head, struct message *msg)

  319. {

  320. printf("********Server Msg*********\n");

  321. printf("msg: %s\n", msg->mtext);

  322. printf("***************************\n");

  323. brocast_msg(socket_fd, head, msg);

  324. return ;

  325. }

  326. void server_quit(int socket_fd, struct node *head, struct message *msg)

  327. {

  328. brocast_msg(socket_fd, head, msg);

  329. kill(getppid(), SIGUSR1);

  330. return ;

  331. }

  332. void print_online(int socket_fd, struct node *head, struct message *msg)

  333. {

  334. struct node *p = head->next;

  335. struct sockaddr_in my_addr;

  336. char buf[512];

  337. printf("%s is request to print online client\n", msg->name);

  338. memset(buf, 0, sizeof(buf));

  339. while (p != NULL)

  340. {

  341. if (strcmp(p->name, msg->name) == 0){

  342. my_addr = p->client_addr;

  343. p = p->next;

  344. continue;

  345. }

  346. strcat(buf, p->name);

  347. strcat(buf, " ");

  348. p = p->next;

  349. }

  350. strcpy(msg->mtext, buf);

  351. msg->type = PRINT_ONLINE;

  352. if (sendto(socket_fd, msg, sizeof(struct message), 0,

  353. (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0){

  354. perror("failed to send print_online message");

  355. exit(-1);

  356. }

  357. return ;

  358. }

  359. void private_chat(int socket_fd, struct node *head, struct message *msg)

  360. {

  361. struct node *p = head->next;

  362. struct sockaddr_in *peer_addr = NULL;

  363. printf("******** Private Msg ********\n");

  364. printf("from %s\n", msg->name);

  365. printf("to %s\n", msg->peer_name);

  366. printf("msg: %s\n", msg->mtext);

  367. printf("*****************************\n");

  368. while (p != NULL)

  369. {

  370. if (strcmp(p->name, msg->peer_name) == 0){

  371. peer_addr = &(p->client_addr);

  372. break;

  373. }

  374. p = p->next;

  375. }

  376. if(!peer_addr){

  377. printf("[Udp server] user %s is not in online list!!\n", msg->peer_name);

  378. msg->type = SERVER_CHAT;

  379. sprintf(msg->mtext, "The one of %s who you want to talk is not exist!!!\n", msg->peer_name);

  380. p = head->next;

  381. while (p != NULL){

  382. if (strcmp(p->name, msg->name) == 0){

  383. peer_addr = &(p->client_addr);

  384. break;

  385. }

  386. p = p->next;

  387. }

  388. }

  389. if(peer_addr){

  390. if (sendto(socket_fd, msg, sizeof(struct message), 0,

  391. (struct sockaddr *)peer_addr, sizeof(struct sockaddr_in)) < 0){

  392. perror("failed to send private message");

  393. exit(-1);

  394. }

  395. }

  396. return ;

  397. }

  398. void heart_beat(int socket_fd, struct node *head, struct message *msg)

  399. {

  400. struct node *p = head->next;

  401. printf("%s heart beat ^^^\n", msg->name);

  402. while (p != NULL)

  403. {

  404. if (strcmp(p->name, msg->name) == 0){

  405. p->client_status = E_CLIENT_ON_LINE;

  406. clock_gettime(CLOCK_REALTIME, &p->heart_beat_time);

  407. }

  408. p = p->next;

  409. }

  410. return ;

  411. }

  412. void brocast_msg(int socket_fd, struct node *head, struct message *msg)

  413. {

  414. struct node *p = head->next;

  415. while(p != NULL)

  416. {

  417. if (msg->type == CLIENT_LOGIN){

  418. if (strcmp(p->name, msg->name) == 0){

  419. p = p->next;

  420. continue;

  421. }

  422. }

  423. sendto(socket_fd, msg, sizeof(struct message), 0, (struct sockaddr *)&(p->client_addr), sizeof(struct sockaddr));

  424. p = p->next;

  425. }

  426. return ;

  427. }

客户端代码:

 
 
  1. #include <stdio.h>

  2. #include <stdlib.h>

  3. #include <string.h>

  4. #include <sys/types.h>

  5. #include <sys/socket.h>

  6. #include <arpa/inet.h>

  7. #include <unistd.h>

  8. #include <signal.h>

  9. #include <pthread.h>

  10. #include <sys/timerfd.h>

  11. #include <sys/epoll.h>

  12. #define UDP_PORT_NUM (8888)

  13. #define CLIENT_LOGIN 100

  14. #define CLIENT_CHAT 200

  15. #define CLIENT_QUIT 300

  16. #define SERVER_CHAT 400

  17. #define SERVER_QUIT 500

  18. #define PRINT_ONLINE 600

  19. #define PRIVATE_CHAT 700

  20. #define HEART_BEAT 800

  21. static char s_my_name[20];

  22. static int s_server_fd;

  23. static int s_epoll_fd = -1;

  24. struct message

  25. {

  26. long type;

  27. char name[20];

  28. char peer_name[20];

  29. char mtext[512];

  30. };

  31. void recv_message(int );

  32. void send_message(int , struct sockaddr_in *, char *, pid_t);

  33. void login_msg(struct message *);

  34. void group_msg(struct message *);

  35. void quit_msg(struct message *);

  36. void server_msg(struct message *);

  37. void server_quit(void);

  38. void online_msg(struct message *);

  39. void private_msg(struct message *);

  40. void print_online(int , struct message *, struct sockaddr_in *);

  41. void group_chat(int , struct message *, struct sockaddr_in *);

  42. void private_chat(int ,struct message *, struct sockaddr_in *);

  43. void client_quit(int , struct message *, struct sockaddr_in *, pid_t );

  44. static void epollAddEvent(int epollFd, int addFd, int state)

  45. {

  46. struct epoll_event ev;

  47. ev.events = state;

  48. ev.data.fd = addFd;

  49. epoll_ctl(epollFd, EPOLL_CTL_ADD, addFd, &ev);

  50. return;

  51. }

  52. void heart_beat(struct sockaddr_in *server_addr)

  53. {

  54. struct message msg;

  55. msg.type = HEART_BEAT;

  56. strcpy(msg.name, s_my_name);

  57. if (sendto(s_server_fd, &msg, sizeof(struct message), 0,

  58. (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){

  59. perror("failed to send online message");

  60. return;

  61. }

  62. return ;

  63. }

  64. void* heart_beat_thread(void* user)

  65. {

  66. struct sockaddr_in *server_addr = (struct sockaddr_in*)user;

  67. struct epoll_event events[1] = {0};

  68. int cnt = 0;

  69. while(1)

  70. {

  71. int fireEvents = epoll_wait(s_epoll_fd, events, 1, -1);

  72. if(fireEvents > 0){

  73. printf("I heart beat\n");

  74. uint64_t exp;

  75. ssize_t size = read(events[0].data.fd, &exp, sizeof(uint64_t));

  76. if(size != sizeof(uint64_t)) {

  77. printf("read error!\n");

  78. }

  79. heart_beat(server_addr);

  80. }

  81. else{

  82. printf("fireEvents = %d", fireEvents);

  83. }

  84. }

  85. return NULL;

  86. }

  87. int main(int argc, char *argv[])

  88. {

  89. pid_t pid;

  90. int server_fd;

  91. struct sockaddr_in server_addr;

  92. if (argc < 4){

  93. fprintf(stderr, "usages: %s ip name heart_beat(seconds)\n", argv[0]);

  94. exit(-1);

  95. }

  96. int heart_beat_period = atoi(argv[3]);

  97. if ((server_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){

  98. perror("failed to create server_fd");

  99. exit(-1);

  100. }

  101. s_server_fd = server_fd;

  102. server_addr.sin_family = AF_INET;

  103. server_addr.sin_port = htons(UDP_PORT_NUM);

  104. server_addr.sin_addr.s_addr = inet_addr(argv[1]);

  105. if ((pid = fork()) < 0){

  106. perror("failed to fork pid");

  107. exit(-1);

  108. }

  109. memset(s_my_name, '\0', 20);

  110. memcpy(s_my_name, argv[2], sizeof(char) * (strlen(argv[2]) + 1));

  111. if (pid == 0) {

  112. /* create epoll */

  113. int epollFd = -1;

  114. epollFd = epoll_create(1);

  115. s_epoll_fd = epollFd;

  116. /* create timer */

  117. int timerFd = -1;

  118. timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);

  119. /* add timer fd to epoll monitor event */

  120. epollAddEvent(epollFd, timerFd, EPOLLIN);

  121. /* create heart beat thread */

  122. pthread_t threadId = -1;

  123. pthread_create(&threadId, NULL, &heart_beat_thread, (void*)&server_addr);

  124. /* create timer, time out is heart beat seconds */

  125. struct itimerspec its;

  126. its.it_interval.tv_sec = heart_beat_period;

  127. its.it_interval.tv_nsec = 0;

  128. its.it_value.tv_sec = heart_beat_period;

  129. its.it_value.tv_nsec = 0;

  130. if (timerfd_settime(timerFd, 0, &its, NULL) < 0) {

  131. fprintf(stderr, "timerfd_settime error\n");

  132. }

  133. recv_message(server_fd);

  134. }

  135. else {

  136. send_message(server_fd, &server_addr, argv[2], pid);

  137. }

  138. return 0;

  139. }

  140. void recv_message(int server_fd)

  141. {

  142. struct message msg;

  143. while (1)

  144. {

  145. memset(&msg, 0, sizeof(msg));

  146. int nbytes = 0;

  147. if ((nbytes = recvfrom(server_fd, &msg, sizeof(msg), 0, NULL, NULL)) < 0){

  148. perror("failed to recv server message");

  149. exit(-1);

  150. }

  151. switch(msg.type)

  152. {

  153. case CLIENT_LOGIN:

  154. login_msg(&msg);

  155. break;

  156. case CLIENT_CHAT:

  157. group_msg(&msg);

  158. break;

  159. case CLIENT_QUIT:

  160. quit_msg(&msg);

  161. break;

  162. case SERVER_CHAT:

  163. server_msg(&msg);

  164. break;

  165. case SERVER_QUIT:

  166. server_quit();

  167. break;

  168. case PRINT_ONLINE:

  169. online_msg(&msg);

  170. break;

  171. case PRIVATE_CHAT:

  172. private_msg(&msg);

  173. break;

  174. default:

  175. break;

  176. }

  177. }

  178. return ;

  179. }

  180. void send_message(int server_fd, struct sockaddr_in *server_addr, char *name, pid_t pid)

  181. {

  182. struct message msg;

  183. char buf[512];

  184. int c;

  185. msg.type = CLIENT_LOGIN;

  186. strcpy(msg.name, name);

  187. if (sendto(server_fd, &msg, sizeof(msg), 0,

  188. (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){

  189. perror("failed to send login message");

  190. exit(-1);

  191. }

  192. while(1)

  193. {

  194. usleep(500);

  195. printf("#####################################\n");

  196. printf("the following options can be choose:\n");

  197. printf("input 1 is to print online client\n");

  198. printf("input 2 is to chat to all the client\n");

  199. printf("input 3 is to chat to only one client\n");

  200. printf("input q is to quit\n");

  201. printf("#####################################\n");

  202. printf(">");

  203. c = getchar();

  204. while (getchar() != '\n');

  205. switch(c)

  206. {

  207. case '1':

  208. print_online(server_fd, &msg, server_addr);

  209. break;

  210. case '2':

  211. printf("[Notice:]you can input <quit> cmd to close group chat....\n");

  212. group_chat(server_fd, &msg, server_addr);

  213. break;

  214. case '3':

  215. printf("[Notice:]you can input <quit> cmd to close private chat....\n");

  216. private_chat(server_fd, &msg, server_addr);

  217. break;

  218. case 'q':

  219. client_quit(server_fd, &msg, server_addr, pid);

  220. break;

  221. default:

  222. break;

  223. }

  224. }

  225. return ;

  226. }

  227. void login_msg(struct message *msg)

  228. {

  229. printf("********Login In Notice********\n");

  230. printf("%s has Login In, you can talk to him/her.\n", msg->name);

  231. printf("****************************\n");

  232. return ;

  233. }

  234. void group_msg(struct message *msg)

  235. {

  236. printf("******** Group Msg ********\n");

  237. printf("name: %s\n", msg->name);

  238. printf("msg: %s\n", msg->mtext);

  239. printf("******** Group Msg ********\n");

  240. return ;

  241. }

  242. void quit_msg(struct message *msg)

  243. {

  244. printf("######## Quit Msg ########\n");

  245. printf("%s is Quit\n", msg->name);

  246. printf("######## Quit Msg ########\n");

  247. return ;

  248. }

  249. void server_msg(struct message *msg)

  250. {

  251. printf("******** Server Msg ********\n");

  252. printf("msg: %s\n", msg->mtext);

  253. printf("******** Server Msg ********\n");

  254. return ;

  255. }

  256. void server_quit(void )

  257. {

  258. kill(getppid(), SIGKILL);

  259. exit(0);

  260. }

  261. void online_msg(struct message *msg)

  262. {

  263. printf("******** Clients you can talk to. ********\n");

  264. printf("Clients: %s\n", msg->mtext);

  265. printf("******** Clients you can talk to. ********\n");

  266. return ;

  267. }

  268. void private_msg(struct message *msg)

  269. {

  270. printf("******** Private Msg ********\n");

  271. printf("[%s] say: %s\n", msg->name, msg->mtext);

  272. printf("******** Private Msg ********\n");

  273. return ;

  274. }

  275. void print_online(int server_fd, struct message *msg, struct sockaddr_in *server_addr)

  276. {

  277. msg->type = PRINT_ONLINE;

  278. if (sendto(server_fd, msg, sizeof(struct message), 0,

  279. (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){

  280. perror("failed to send online message");

  281. exit(-1);

  282. }

  283. return ;

  284. }

  285. void group_chat(int server_fd, struct message *msg, struct sockaddr_in *server_addr)

  286. {

  287. char buf[512];

  288. memset(buf, 0, sizeof(buf));

  289. printf("*********** Group Chat Room ***********\n");

  290. printf("****** Welcome to group chat room ******\n");

  291. printf("* if you want to quit, please input quit\n");

  292. printf("****************************************\n");

  293. while(1)

  294. {

  295. memset(buf, 0, sizeof(buf));

  296. usleep(500);

  297. printf(">");

  298. fgets(buf, sizeof(buf), stdin);

  299. buf[strlen(buf) - 1] = 0;

  300. msg->type = CLIENT_CHAT;

  301. strcpy(msg->mtext, buf);

  302. if (strncmp(buf, "quit", 4) == 0)

  303. break;

  304. if (sendto(server_fd, msg, sizeof(struct message), 0,

  305. (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){

  306. perror("failed to send group message");

  307. exit(-1);

  308. }

  309. }

  310. return ;

  311. }

  312. void private_chat(int server_fd, struct message *msg, struct sockaddr_in *server_addr)

  313. {

  314. char name[20];

  315. char buf[512];

  316. memset(name, 0, sizeof(name));

  317. printf("please input the peer_name\n");

  318. printf(">");

  319. fgets(name, sizeof(name), stdin);

  320. name[strlen(name) - 1] = 0;

  321. if(strncmp(s_my_name, name, strlen(name)) == 0){

  322. printf("you can not talk with yourself!!!!!\n");

  323. return;

  324. }

  325. strcpy(msg->peer_name, name);

  326. msg->type = PRIVATE_CHAT;

  327. printf("you want to talk to %s!\n", msg->peer_name);

  328. while(1)

  329. {

  330. usleep(500);

  331. printf(">");

  332. fgets(buf, sizeof(buf), stdin);

  333. buf[strlen(buf) - 1] = 0;

  334. strcpy(msg->mtext, buf);

  335. if (strncmp(buf, "quit", 4) == 0)

  336. break;

  337. if (sendto(server_fd, msg, sizeof(struct message), 0,

  338. (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){

  339. perror("failed to send private message");

  340. exit(-1);

  341. }

  342. }

  343. return ;

  344. }

  345. void client_quit(int server_fd, struct message *msg, struct sockaddr_in *server_addr, pid_t pid)

  346. {

  347. msg->type = CLIENT_QUIT;

  348. if (sendto(server_fd, msg, sizeof(struct message), 0,

  349. (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0){

  350. perror("failed to send quit message");

  351. exit(-1);

  352. }

  353. kill(pid, SIGKILL);

  354. waitpid(pid, NULL, 0);

  355. exit(0);

  356. }

(58条消息) 学习笔记:UDP实现进程心跳检测_fanchenxinok的专栏-CSDN博客_udp 心跳包

Guess you like

Origin blog.csdn.net/tjcwt2011/article/details/121851014