linux下socket编程

综合unp前五章,写了一个服务器-客户端程序。

主要功能:客户端从标准输入读入字符串发送到服务器,服务器显示。服务器接受连接后,fork()子进程实现具体操作。

服务器主要过程:

socket()->bind()->listen()->accept()->read(),服务器在accept一个clientfd后,fork()一个子进程服务。

客户端:

socket()->connect()->write(),客户端用poll处理服务器socket和标准输入。

测试结果:

(1)新建服务器、客户端

server的父进程处于监听状态,两个子进程和client处于建立连接状态。

 

(2)传数据,client发送“OFF”表示关闭连接

   

 

(3)关闭连接后的端口状态

 

 

服务器代码:

 1 #include <stdio.h>
 2 #include <sys/socket.h>
 3 #include <sys/types.h>
 4 #include <arpa/inet.h>
 5 #include <netinet/in.h>
 6 #include <unistd.h>
 7 #include <string.h>
 8 #include <stdlib.h>
 9 #include <sys/wait.h>
10 #include <signal.h>
11 
12 void sig_act(int signo) {
13     pid_t pid;
14     while ( (pid = waitpid(-1, 0, WNOHANG)) > 0 );
15 }
16 
17 void foo(struct sockaddr_in addr, int fd) {
18     char buff[1024];
19     int len;
20     inet_ntop(AF_INET, &addr.sin_addr, buff, sizeof(buff));
21     printf("connction from %s, port %d\n", buff, ntohs(addr.sin_port));
22     while(1) {
23         len = read(fd, buff, 1024);
24         if (len > 0) {
25             write(fd, buff, 1024);
26             printf("receive from %d: %s\n", ntohs(addr.sin_port), buff);
27         }
28         else {
29             close(fd);
30             break;
31         }
32     }
33 }
34 int main() {
35     pid_t pid;
36     int serverfd, clientfd;
37     struct sockaddr_in serveraddr, clientaddr;
38     socklen_t clientaddr_len;
39     u_short port = 9999;
40     char buff[1024];
41     serverfd = socket(AF_INET, SOCK_STREAM, 0);
42     if (serverfd == -1) {
43         printf("socket error\n");
44         exit(0);
45     }
46     bzero(&serveraddr, sizeof(serveraddr));
47     serveraddr.sin_family = AF_INET;
48     serveraddr.sin_port = htons(port);
49     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
50     if (bind(serverfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) {
51         printf("bind error\n");
52         exit(0);
53     }
54     inet_ntop(AF_INET, &serveraddr.sin_addr, buff, sizeof(buff));
55     printf("server ip is %s running on port %d\n", buff, ntohs(serveraddr.sin_port));
56 
57     if ( listen(serverfd, 1) == -1 ) {
58         printf("listen error\n");
59         exit(0);
60     }
61     signal(SIGCHLD, sig_act);
62     while(1) {
63         clientaddr_len = sizeof(clientaddr);
64         clientfd = accept(serverfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
65         if ((pid = fork()) == 0) {
66             close(serverfd);
67             foo(clientaddr, clientfd);
68             exit(0);
69         }
70         close(clientfd);
71     }
72     close(serverfd);
73     exit(0);
74 }

 

客户端代码:

 1 #include <stdio.h>
 2 #include <sys/socket.h>
 3 #include <sys/types.h>
 4 #include <arpa/inet.h>
 5 #include <netinet/in.h>
 6 #include <unistd.h>
 7 #include <string.h>
 8 #include <stdlib.h>
 9 #include <poll.h>
10 
11 int main() {
12     int clientfd;
13     struct sockaddr_in clientaddr;
14     char buff[1024];
15     struct pollfd eventfd[2];
16     clientfd = socket(AF_INET, SOCK_STREAM, 0);
17     if (clientfd == -1) {
18         printf("socket error\n");
19         exit(0);
20     }
21     clientaddr.sin_family = AF_INET;
22     clientaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
23     clientaddr.sin_port = htons(9999);
24     if (connect(clientfd, (struct sockaddr *)&clientaddr, sizeof(clientaddr)) == -1) {
25         printf("connet error\n");
26         exit(0);
27     }
28     eventfd[0].fd = clientfd;
29     eventfd[0].events = POLLRDNORM;
30     eventfd[1].fd = fileno(stdin);
31     eventfd[1].events = POLLRDNORM | POLLWRNORM;
32     int nready;
33     int stdineof = 0;
34     int i;
35     while (1) {
36         nready = poll(eventfd, 2, -1);
37 
38         if (eventfd[0].revents & (POLLRDNORM | POLLERR)) {
39             if ( (i = read(clientfd, buff, 1024)) == 0 ) {
40                 if (stdineof == 1)
41                     break;
42                 else {
43                     printf("server closed!\n");
44                     eventfd[0].fd = -1;
45                     shutdown(clientfd, SHUT_WR);
46                     break;
47                 }
48             }
49             else {
50                 printf("%s\n", buff);
51             }
52         }
53         
54         if ( eventfd[1].revents & POLLRDNORM ) {
55             scanf("%s", buff);
56             if (strcmp(buff, "OFF") == 0){
57                 eventfd[1].fd = -1;
58                 stdineof = 1;
59                 shutdown(clientfd, SHUT_WR);
60                 continue;
61             }
62             write(clientfd, buff, 1024);
63         }
64     }
65     close(clientfd);
66     exit(0);
67 }

 

posted @ 2018-05-29 19:48  Zzz...y  阅读(183)  评论(0编辑  收藏  举报