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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)