zoukankan      html  css  js  c++  java
  • 点对点 客户端-服务器 聊天程序

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

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

    服务器端:

     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
    ",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
    手里拿着一把锤子,看什么都像钉子,编程界的锤子应该就是算法了吧!
  • 相关阅读:
    Anagram
    HDU 1205 吃糖果(鸽巢原理)
    Codeforces 1243D 0-1 MST(补图的连通图数量)
    Codeforces 1243C Tile Painting(素数)
    Codeforces 1243B2 Character Swap (Hard Version)
    Codeforces 1243B1 Character Swap (Easy Version)
    Codeforces 1243A Maximum Square
    Codeforces 1272E Nearest Opposite Parity(BFS)
    Codeforces 1272D Remove One Element
    Codeforces 1272C Yet Another Broken Keyboard
  • 原文地址:https://www.cnblogs.com/chess/p/4684771.html
Copyright © 2011-2022 走看看