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
    手里拿着一把锤子,看什么都像钉子,编程界的锤子应该就是算法了吧!
  • 相关阅读:
    前端开发框架
    用C#实现的条形码和二维码编码解码器
    Razor视图语法
    asp.net微软图表控件MsChart
    高并发下的Node.js与负载均衡
    GCC知识
    Mongodb学习(安装篇): 在centos下的安装
    代码评审
    构建一个前端库做一个富客户端的基类
    企业级应用架构(NHibernater+Spring.Net+MVC3+WCF)_3.0
  • 原文地址:https://www.cnblogs.com/chess/p/4684771.html
Copyright © 2011-2022 走看看