棋子

导航

点对点 客户端-服务器 聊天程序

  服务器,客户端都是父进程、子进程分别负责发送、接收字符串。

  另外使用了信号函数来发送和接收处理信号,比如当子进程结束时,传递一个信号给父进程,然后父进程会执行信号处理函数。

服务器端:

 1 #include<stdio.h>
 2 #include<unistd.h>
 3 #include<sys/types.h>
 4 #include<sys/socket.h>
 5 #include<errno.h>
 6 #include<netinet/in.h>
 7 #include<string.h>
 8 #include<stdlib.h>
 9 #include<signal.h>
10 
11 void handler(int sig)//这是信号处理函数
12 {
13     printf("recv a sig:%d",sig);
14     exit(EXIT_SUCCESS);
15 }
16 
17 int main()
18 {
19     int sockfd=socket(AF_INET,SOCK_STREAM,0);
20     if(sockfd<0) perror("socket!!!!");
21     
22     int on=1;
23     int result=setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));//启用套接字选项,必须在bind之前完成
24     if(result<0) perror("setsockopt");
25 
26     struct sockaddr_in server_addr;
27     memset(&server_addr,0,sizeof(server_addr));
28     server_addr.sin_family=AF_INET;
29     server_addr.sin_port=htons(888);
30     server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
31 
32 
33     int res=bind(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
34     if(res<0)perror("bind!!!");
35 
36     res=listen(sockfd,50);
37     if(res<0) perror("listen!!");
38 
39     int conn_fd;
40     struct sockaddr_in peeraddr;
41     int addr_len=sizeof(peeraddr);
42     pid_t pid;
43     
44         conn_fd=accept(sockfd,(struct sockaddr*)&peeraddr,&addr_len);
45                 if(conn_fd<0)perror("accept!!");
46         printf(" the ip of client:%s,the port of client:%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));//打印对等方的ip与端口
47         
48         //signal(SIGUSR1,handler);
49         pid=fork();
50         if(pid<0)
51             perror("fork failed");
52         else if(pid==0)
53         {            //子进程
54             char recvbuf[1024]={0};
55             while(1)
56             {
57                 memset(recvbuf,0,sizeof(recvbuf));
58                 int resu;
59                 resu=read(conn_fd,recvbuf,sizeof(recvbuf));
60                 if(resu<0)perror("read");
61                 else if(resu==0)
62                 { 
63                     printf("peer closed!!!!");
64                     //exit(EXIT_SUCCESS);
65                     kill(getppid(),SIGUSR1);//发送一个信号给父进程
66                     break;
67                 }
68                 fputs(recvbuf,stdout);
69             }
70             //close(conn_fd);
71             //close(sockfd);
72             exit(EXIT_SUCCESS);
73         }
74         else //父进程
75         {
76             signal(SIGUSR1,handler);//安装信号接收函数
77             char sendbuf[1024]={0};
78             while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
79             {
80                 write(conn_fd,sendbuf,strlen(sendbuf));
81                 memset(sendbuf,0,sizeof(sendbuf));
82         }
83         //close(conn_fd);
84         //close(sockfd);
85         exit(EXIT_SUCCESS);
86         }
87         return 0;
88 }

客户端:

 1 #include<stdio.h>
 2 #include<unistd.h>
 3 #include<sys/types.h>
 4 #include<sys/socket.h>
 5 #include<errno.h>
 6 #include<netinet/in.h>
 7 #include<string.h>
 8 #include<stdlib.h>
 9 int main()
10 {
11     int sockfd= socket(AF_INET,SOCK_STREAM,0);
12     if(sockfd<0)perror("socket");
13 
14     struct sockaddr_in server_addr;
15     memset(&server_addr,0,sizeof(server_addr));
16     server_addr.sin_family=AF_INET;
17     server_addr.sin_port=htons(888);    //this port number is owned by server,and client's port number is appointed by random
18     server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器端的ip地址
19 
20     int res=connect(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
21     if(res<0)perror("connect!!!!!!!");
22 
23     pid_t pid;
24     pid=fork();
25     if(pid<0)perror("fork");
26     if(0==pid)//子进程
27     {
28         char recvbuf[1024];
29         int ret;
30         while(1)
31         {
32             memset(recvbuf,0,sizeof(recvbuf));//防止空间中的内容干涉,拖泥带水
33             ret=read(sockfd,recvbuf,sizeof(recvbuf));
34             if(ret<0)perror("read");
35             if(ret==0)
36             {
37                 printf("peer closed!!!!!!!");
38                 break;
39             }
40             fputs(recvbuf,stdout);
41         }
42         close(sockfd);
43     }
44     else
45     {
46         char sendbuf[1024];
47         while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL){
48         write(sockfd,sendbuf,strlen(sendbuf));
49         memset(sendbuf,0,sizeof(sendbuf));
50     }
51     //exit(EXIT_SUCCESS);}
52     close(sockfd);
53     }
54     return 0;
55 }
View Code

 

posted on 2015-07-29 00:06  鼬与轮回  阅读(437)  评论(0编辑  收藏  举报