【十二】进程间通信——[BSD]套接字(socket)

来源:互联网 发布:查询淘宝关键词排名 编辑:程序博客网 时间:2024/05/01 14:54

【十二】 进程间通信——[BSD]套接字(socket)

/*sever.c*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define N 64#define R 1#define B 2#define U 3#define E 4typedef struct{int type;char name[16];char text[N];} MSG;typedef struct _node_{struct sockaddr_in cliaddr;struct _node_ *next;} linknode, *linklist;typedef struct sockaddr SA;void AddUser(int sockfd, MSG buf, struct sockaddr_in peeraddr, linklist h){linklist p;p = (linklist)malloc(sizeof(linknode));p->cliaddr = peeraddr;p->next = h->next;h->next = p;sprintf(buf.text, "%s is online\n", buf.name);strcpy(buf.name, "system");p = p->next;while (p != NULL){sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&p->cliaddr, sizeof(peeraddr));p = p->next;}strcpy(buf.text, "Welcome To Farsight Chat Room\n");sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&peeraddr, sizeof(peeraddr));return;}void DelUser(int sockfd, MSG buf, struct sockaddr_in peeraddr, linklist h){linklist p = h->next;sprintf(buf.text, "%s is offline\n", buf.name);strcpy(buf.name, "system");while (p != NULL){if (memcmp(&peeraddr, &p->cliaddr, sizeof(peeraddr)) == 0){h->next = p->next;free(p);}else{sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&p->cliaddr, sizeof(peeraddr));h = h->next;}p = h->next;}strcpy(buf.text, "See You Next Time\n");sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&peeraddr, sizeof(peeraddr));return;}void Broadcast(int sockfd, MSG buf, linklist h){h = h->next;while (h != NULL){sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&h->cliaddr, sizeof(h->cliaddr));h = h->next;}return;}int main(int argc, char *argv[]){int sockfd;struct sockaddr_in myaddr, peeraddr;socklen_t peerlen;MSG buf;pid_t pid;if (argc < 3){printf("Usage : %s <ip> <port>\n", argv[0]);exit(-1);}// XXX int socket(int domain, int type, int protocol);if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){perror("fail to socket");exit(-1);}// XXX int bind(int sockfd, const struct sockaddr *addr,//              socklen_t addrlen);bzero(&myaddr, sizeof(myaddr));myaddr.sin_family = PF_INET;myaddr.sin_port = htons(atoi(argv[2]));myaddr.sin_addr.s_addr = inet_addr(argv[1]);if (bind(sockfd, (SA *)&myaddr, sizeof(myaddr)) < 0){perror("fail to bind");exit(-1);}if ((pid = fork()) < 0){perror("fail to fork");exit(-1);}else if (pid == 0)  // dispatch message{linklist h = (linklist)malloc(sizeof(linknode));h->next = NULL;peerlen = sizeof(peeraddr);while ( 1 ){recvfrom(sockfd, &buf, sizeof(buf), 0, (SA *)&peeraddr, &peerlen);switch ( buf.type ){case R :AddUser(sockfd, buf, peeraddr, h);break;case U :DelUser(sockfd, buf, peeraddr, h);break;case B :case E :Broadcast(sockfd, buf, h);break;}}}else  // send message{strcpy(buf.name, "system");buf.type = B;while ( 1 ){printf("server > ");fgets(buf.text, N, stdin);if (strncmp(buf.text, "quit\n", 5) == 0) break;sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&myaddr, sizeof(myaddr));usleep(100000);}buf.type = E;sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&myaddr, sizeof(myaddr));usleep(100000);kill(pid, SIGUSR1);exit(0);}return 0;}

/*client.c*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define N 64#define R 1#define B 2#define U 3#define E 4typedef struct{int type;char name[16];char text[N];} MSG;typedef struct sockaddr SA;int main(int argc, char *argv[]){int sockfd;struct sockaddr_in servaddr;MSG buf;pid_t pid;if (argc < 3){printf("Usage : %s <ip> <port>\n", argv[0]);exit(-1);}printf("please input your name : ");fgets(buf.name, 16, stdin);buf.name[strlen(buf.name)-1] = '\0';// XXX int socket(int domain, int type, int protocol);if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){perror("fail to socket");exit(-1);}// XXX int bind(int sockfd, const struct sockaddr *addr,//              socklen_t addrlen);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = PF_INET;servaddr.sin_port = htons(atoi(argv[2]));servaddr.sin_addr.s_addr = inet_addr(argv[1]);buf.type = R;sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr));  // registerif ((pid = fork()) < 0){perror("fail to fork");exit(-1);}else if (pid == 0)  // recv message{while ( 1 ){recvfrom(sockfd, &buf, sizeof(buf), 0, NULL, NULL);if (buf.type == E) break;printf("\n *** [%s] %s", buf.name, buf.text);}printf("Server is down, exit...\n");kill(getppid(), SIGUSR1);exit(0);}else  // send message{buf.type = B;while ( 1 ){printf("client > ");fgets(buf.text, N, stdin);if (strncmp(buf.text, "quit\n", 5) == 0) break;sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr));usleep(100000);}buf.type = U;sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr));usleep(100000);kill(pid, SIGUSR1);exit(0);}return 0;}


原创粉丝点击