• linux c语言fork socket 并发回射服务器


    重点:accept后fork,子进程和父进程共享两个fd,一个是 监听fd,一个是客户端socketfd,。

    子进程需要关闭监听套接字fd,父进程需要关闭客户端套接字fd进行继续accept.

    这样子进程就可以对客户端进行读写了。

    服务器代码.c

    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    int BUF_SIZE=1024;
    int main()
    {
    int serv_sockfd;
    int client_sockfd;
    char buf[BUF_SIZE];
    memset(buf,0,sizeof(buf));
    
    struct sockaddr_in serv_addr;
    struct sockaddr_in client_addr;
    
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=INADDR_ANY;
    serv_addr.sin_port=htons(8888);
    if((serv_sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
    {
    printf("socket error!");
    return -1;
    }
    if(bind(serv_sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
    {
    perror("bind error");
    return -2;
    }
    if(listen(serv_sockfd,5)<0)
    {
    printf("listen error");
    return -3;
    }else{
    printf("listening ....");
    }
    socklen_t sin_size;
    sin_size=sizeof(client_addr);
    /****************************
    *accept后服务器阻塞,直到有新的客户端请求到达
    *从accept返回client_sockfd,这是一个客户端套接字口,可以进行读写
    *并发服务器fork之后,server_sockfd,以及client_sockfd,都会在子进程和父进程之间共享,(实际是引用计数变成2)
    *(重点)然后父进程关闭已经连接的套接字口client_sockfd,子进程关闭监听套接字口,这样子进程就可以操作客户端,父进程就可以继续accept,
    *最后子进程还需要 关闭连接,以及return 退出进程。
    *
    * *****************************/
    while(1)
    {
    if((client_sockfd=accept(serv_sockfd,(struct sockaddr*)&client_addr,&sin_size))<0)
    {
    perror("accept error!");
    return -1;
    }
    if(fork()==0)
    {
    close(serv_sockfd);
    int len=recv(client_sockfd,buf,sizeof(buf),0);
    printf("%s
    ",buf);
    send(client_sockfd,buf,len,0);
    
    close(client_sockfd);
    return -1;
    }else{
    close(client_sockfd);
    }
    }
    
    }

    客户端qt(c++)

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include<QHostAddress>
    #include<QMessageBox>
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    this->socket=new QTcpSocket();
    this->socket->connectToHost(QHostAddress("127.0.0.1"),8888);
    this->connect(this->socket,SIGNAL(connected()),this,SLOT(slotConn()));
    this->connect(this->socket,SIGNAL(readChannelFinished()),this,SLOT(slotRecvid()));
    }
    
    MainWindow::~MainWindow()
    {
    delete ui;
    }
    void MainWindow::slotConn()
    {
    QMessageBox::about(this,"x","连接成功");
    this->socket->write("this is data!");
    }
    void MainWindow::slotRecvid()
    {
    QString s=this->socket->readAll();
    QMessageBox::about(this,"回射服务器",s);
    }

     

    ————————————————
    版权声明:本文为CSDN博主「涵涵YH」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/u012997311/article/details/72614625

  • 相关阅读:
    linux进程调度(zz)
    为什么vfork的子进程里用return,整个程序会挂掉,而且exit不会(zz)
    ubuntu安装samba
    【前端知乎系列】ArrayBuffer 和 Blob 对象
    【Web技术】442- 关于图片懒加载的几种方案
    【Web技术】441- 蚂蚁前端研发最佳实践
    【面试题】440- 10 道 Nodejs EventLoop 和事件相关面试题
    【面试题】439- 这是一道网红面试题
    【Web技术】438- 移动端体验优化经验总结与实践
    记 · 寒风依旧 · 虎跑路和人生路
  • 原文地址:https://www.cnblogs.com/ip99/p/12126526.html
Copyright © 2020-2023  润新知