首页 > 技术文章 > Ubuntu下实现回射服务器-处理客户端连接断开后服务器响应(四)

simon-xie 2021-05-28 18:09 原文

服务器端程序如下: 

 

 1 #include<stdio.h>
 2 #include <sys/types.h>          /* See NOTES */
 3 #include <sys/socket.h>
 4 #include <netinet/ip.h>
 5 #include <errno.h>
 6 #include <stdlib.h>
 7 #include <netinet/in.h>
 8 #include <arpa/inet.h>
 9 #include <unistd.h>
10 #include <string.h>
11 void do_service(int conn){
12 
13     char recvbuffer[1024];
14     while(1){
15         memset(recvbuffer,0,sizeof(recvbuffer));
16         int readsize=read(conn,&recvbuffer,sizeof(recvbuffer));
17         if (readsize==0){
18             perror("client disconnect");
19             break;//跳出循环
20         }else if (readsize==-1){
21               perror("read");
22           exit(EXIT_FAILURE);
23         }
24         fputs(recvbuffer,stdout);
25         write(conn,recvbuffer,strlen(recvbuffer));
26     }
27 }
28 int main(){
29     int socketfd;
30     socketfd=socket(PF_INET,SOCK_STREAM,0);
31     if(socketfd<0){
32         perror("socket");
33         exit(EXIT_FAILURE);
34     }
35 
36     struct sockaddr_in sockaddress;
37     sockaddress.sin_family=AF_INET;
38     sockaddress.sin_port=htons(5188);
39     sockaddress.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY接收任何地址的连接
40     //sockaddress.sin_addr.s_addr=inet_addr("127.0.0.1");//也可以是这种方式
41 
42     int on=1;
43     if (setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0){
44         perror("setsockopt");
45         exit(EXIT_FAILURE);
46     }
47 
48     if(bind(socketfd,(struct sockaddr*)&sockaddress,sizeof(sockaddress))<0){
49         perror("bind");
50         exit(EXIT_FAILURE);
51     }
52 
53     if ( listen(socketfd,SOMAXCONN)<0){
54         perror("listen");
55         exit(EXIT_FAILURE);
56     }
57 
58     int conn;
59     struct sockaddr_in peeraddr;
60     socklen_t len=sizeof(struct sockaddr_in);
61     pid_t pid;
62     while(1){
63         conn=accept(socketfd,(struct sockaddr*)&peeraddr,&len);
64         if (conn<0){
65             perror("accept");
66             exit(EXIT_FAILURE);
67         }
68         printf("client ip:%s port:%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
69         pid=fork();
70         if (pid<0){//开启进程失败
71             perror("fork");
72             exit(EXIT_FAILURE);
73         }else if(pid==0){//进入子进程处理过程
74             close(socketfd);
75             do_service(conn);
76             exit(EXIT_SUCCESS);//do_service被break后,子进程就没有存在的必要了,直接退出
77         }else{//主进程处理过程
78             close(conn);//主进程执行到这后就不需要连接套接字了,关闭它
79         }
80     }
81     return 0;
82 
83 }

 

 

 

通过read返回0判断客户端连接断开还是不严谨,可以参考https://www.cnblogs.com/Dennis-mi/articles/6047032.html

 

推荐阅读