#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#include <signal.h>#define CLIENT_LOGIN 100#define CLIENT_CHAT 200#define CLIENT_QUIT 300#define SERVER_CHAT 400#define SERVER_QUIT 500struct message{ long type; char name[20]; char mtext[512];};void recv_message(int );void send_message(int , struct sockaddr_in *, char *, pid_t);void login_msg(struct message *);void group_msg(struct message *);void quit_msg(struct message *);void server_msg(struct message *);void server_quit(void);int main(int argc, char *argv[]){ pid_t pid; int server_fd; struct sockaddr_in server_addr; if (argc < 4) { fprintf(stderr, "usages: %s ip port name\n", argv[0]); exit(-1); } if ((server_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("failed to create server_fd"); exit(-1); } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(atoi(argv[2])); server_addr.sin_addr.s_addr = inet_addr(argv[1]); if ((pid = fork()) < 0) { perror("failed to fork pid"); exit(-1); } if (pid == 0) recv_message(server_fd); else send_message(server_fd, &server_addr, argv[3], pid); return 0;}void recv_message(int server_fd){ struct message msg; while (1) { memset(&msg, 0, sizeof(msg)); if (recvfrom(server_fd, &msg, sizeof(msg), 0, NULL, NULL) < 0) { perror("failed to recv server message"); exit(-1); } switch(msg.type) { case CLIENT_LOGIN: login_msg(&msg); break; case CLIENT_CHAT: group_msg(&msg); break; case CLIENT_QUIT: quit_msg(&msg); break; case SERVER_CHAT: server_msg(&msg); break; case SERVER_QUIT: server_quit(); break; default: break; } } return ;}void send_message(int server_fd, struct sockaddr_in *server_addr, char *name, pid_t pid){ struct message msg; char buf[512]; msg.type = CLIENT_LOGIN; strcpy(msg.name, name); if (sendto(server_fd, &msg, sizeof(msg), 0, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0) { perror("failed to send login message"); exit(-1); } while(1) { memset(buf, 0, sizeof(buf)); memset(&msg, 0, sizeof(msg)); usleep(500); printf(">"); fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] = 0; strcpy(msg.mtext, buf); strcpy(msg.name, name); msg.type = CLIENT_CHAT; if (strncmp(buf, "quit", 4) == 0) { msg.type = CLIENT_QUIT; if (sendto(server_fd, &msg, sizeof(msg), 0, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0) { perror("failed to send quit message"); exit(-1); } kill(pid, SIGKILL); waitpid(pid, NULL, 0); exit(0); } if (sendto(server_fd, &msg, sizeof(msg), 0, (struct sockaddr *)server_addr, sizeof(struct sockaddr)) < 0) { perror("failed to send group message"); exit(-1); } } return ;}void login_msg(struct message *msg){ printf("######## Login in ########\n"); printf("%s is login in\n", msg->name); printf("######## Login in ########\n"); return ;}void group_msg(struct message *msg){ printf("******** Group Msg ********\n"); printf("name: %s\n", msg->name); printf("msg: %s\n", msg->mtext); printf("******** Group Msg ********\n"); return ;}void quit_msg(struct message *msg){ printf("######## Quit Msg ########\n"); printf("%s is Quit\n", msg->name); printf("######## Quit Msg ########\n"); return ;}void server_msg(struct message *msg){ printf("******** Server Msg ********\n"); printf("msg: %s\n", msg->mtext); printf("******** Server Msg ********\n"); return ;}void server_quit(void ){ kill(getppid(), SIGKILL); exit(0);}