p2p点对点通信

参考链接:Linux 网络编程详解三(p2p点对点聊天)https://www.cnblogs.com/zhanggaofeng/p/6131783.html?from=singlemessage&isappinstalled=0

在这里插入图片描述

服务器

void handler(int signo){      
  if(signo==SIGUSR1){        
    printf("child process exit\n");      
    exit(1);       
  }     
}
int main(){        
  int listenfd=socket(PF_INET,SOCK_STREAM,0);       
        
  struct sockaddr_in addr;    
  addr.sin_family=AF_INET;    
  addr.sin_port=htons(8001);  
  addr.sin_addr.s_addr=inet_addr("127.0.0.1");      
  int optval=1;    
  setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));    
  bind(listenfd,(struct sockaddr*)&addr,sizeof(addr));
  listen(listenfd,5);
        
  struct sockaddr_in peer_addr; 
  socklen_t peer_addr_len;    
  int newconn=accept(listenfd,(struct sockaddr*)&peer_addr,&peer_addr_len); 
  if(newconn==-1){ 
    perror("connect fail");   
    close(newconn);   
    return -1;        
  }     
  else  
    printf("accept by %s\n", inet_ntoa(peer_addr.sin_addr));      
  pid_t pid=fork();        
  if(pid==-1){
    perror("fork");
    return -1;
  }   
  if(pid>0){ //父进程接收客户端信息,打屏    
    while(1){      
      char buf[1024];
      int ret=read(newconn,buf,sizeof(buf));        
      if(ret>0)    
        fputs(buf,stdout);   //write(STDOUT_FILENO, buf, ret);  //打印到屏幕上
      else if(ret==0){        
        printf("peer have close\n");   
        close(newconn);  
        break;     
      } 
      else{ //recv error      
        printf("read<0,error\n");        
        break;     
      } 
      memset(buf,0,sizeof(buf));
    } 
    //发送信号,关闭子进程  
    kill(pid,SIGUSR1); // kill signal   
    close(listenfd); 
    close(newconn);   
     
    //wait子进程
    int ret=0;
    while(1)
    {
        ret=wait(NULL);
        printf("子进程pid=%d\n",ret);
        if(ret==-1)
        {
			 if(errno==EINTR)
			     continue;
			 break;
        }
    }     
      
  }     
  else if(pid==0){  //子进程读取用户输入,发送给客户端 
    close(listenfd); //关闭服务器监听套接字
    signal(SIGUSR1,handler);  //安装信号 
        
    char buf[1024];
    while(fgets(buf,sizeof(buf),stdin)!=NULL){ //while(read(STDIN_FILENO, sendbuf, 1024) == -1)      
      write(newconn,buf,strlen(buf));    
      memset(buf,0,sizeof(buf));
    }
  }
}

客户端

int main(){
  int sockfd=socket(PF_INET,SOCK_STREAM,0);
        
  struct sockaddr_in svr_addr;
  svr_addr.sin_family=AF_INET;
  svr_addr.sin_port=htons(8001);
  svr_addr.sin_addr.s_addr=inet_addr("127.0.0.1");  
        
  int ret=connect(sockfd,(struct sockaddr*)&svr_addr,sizeof(svr_addr));   
  if(ret==-1){     
    perror("connect");        
    exit(1);       
  }     
  else  
    printf("connect server sucess\n");   
        
  pid_t pid=fork();  
  if (pid == -1){
      perror("fork() err");
      return -1;
  }
  if(pid>0){ //父进程
    char buf[1024]={0};       
    while(fgets(buf,sizeof(buf),stdin)!=NULL){      
      write(sockfd,buf,strlen(buf));     
      memset(buf,0,sizeof(buf));
    }   
  }       
  else if(pid==0){//子进程接收信息,打屏
    while(1){      
      char buf[1024];
      int ret=read(sockfd,buf,sizeof(buf));
      if(ret>0)    
        fputs(buf,stdout); //打屏   
      else if(ret==0){        
        printf("peer have close\n");   
        close(sockfd);  
        break;     
      } 
      else{        
        printf("read<0,error\n");        
        break;     
      } 
      memset(buf,0,sizeof(buf));
    }   
    close(sockfd); 
    kill(getppid(),SIGKILL);  
    exit(1);       
  }        
  return 0;        
}     

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值