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\n",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

猜你喜欢

转载自www.cnblogs.com/ip99/p/12126526.html