当前位置:网站首页>4-20-4-23 concurrent server, TCP state transition;
4-20-4-23 concurrent server, TCP state transition;
2022-07-03 14:49:00 【III VII】
To achieve TCP The communication server handles concurrent tasks , Use multithreading or multiprocessing to solve .
Ideas :
- A parent process , Multiple subprocesses
2. The parent process is responsible for waiting and accepting the client's connection
3. Subprocesses : Complete communication , Accept a client connection , A child process is created for communication .
Server code :
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <wait.h>
#include <errno.h>
void recyleChild(int arg) {
while(1) {
int ret = waitpid(-1, NULL, WNOHANG);
if(ret == -1) {
// All child processes are recycled
break;
}else if(ret == 0) {
// There are sub processes alive
break;
} else if(ret > 0){
// It's recycled
printf(" Subprocesses %d It's recycled \n", ret);
}
}
}
int main() {
struct sigaction act;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
act.sa_handler = recyleChild;
// Register signal capture
sigaction(SIGCHLD, &act, NULL);
// establish socket
int lfd = socket(PF_INET, SOCK_STREAM, 0);
if(lfd == -1){
perror("socket");
exit(-1);
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(9999);
saddr.sin_addr.s_addr = INADDR_ANY;
// binding
int ret = bind(lfd,(struct sockaddr *)&saddr, sizeof(saddr));
if(ret == -1) {
perror("bind");
exit(-1);
}
// monitor
ret = listen(lfd, 128);
if(ret == -1) {
perror("listen");
exit(-1);
}
// Keep waiting for the client to connect
while(1) {
struct sockaddr_in cliaddr;
int len = sizeof(cliaddr);
// Accept the connection
int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &len);
if(cfd == -1) {
if(errno == EINTR) {
continue;
}
perror("accept");
exit(-1);
}
// Every connection comes in , Create a child process to communicate with the client
pid_t pid = fork();
if(pid == 0) {
// Subprocesses
// Get client information
char cliIp[16];
inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, cliIp, sizeof(cliIp));
unsigned short cliPort = ntohs(cliaddr.sin_port);
printf("client ip is : %s, prot is %d\n", cliIp, cliPort);
// Receive data from client
char recvBuf[1024];
while(1) {
int len = read(cfd, &recvBuf, sizeof(recvBuf));
if(len == -1) {
perror("read");
exit(-1);
}else if(len > 0) {
printf("recv client : %s\n", recvBuf);
} else if(len == 0) {
printf("client closed....\n");
break;
}
write(cfd, recvBuf, strlen(recvBuf) + 1);
}
close(cfd);
exit(0); // Exit the current subprocess
}
}
close(lfd);
return 0;
}
Client code :
// TCP Communication client
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main() {
// 1. Create socket
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1) {
perror("socket");
exit(-1);
}
// 2. Connect to the server side
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.87.128", &serveraddr.sin_addr.s_addr);
serveraddr.sin_port = htons(9999);
int ret = connect(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
if(ret == -1) {
perror("connect");
exit(-1);
}
// 3. signal communication
char recvBuf[1024];
int i = 0;
while(1) {
sprintf(recvBuf, "data : %d\n", i++);
// Send data to the server
write(fd, recvBuf, strlen(recvBuf)+1);
int len = read(fd, recvBuf, sizeof(recvBuf));
if(len == -1) {
perror("read");
exit(-1);
} else if(len > 0) {
printf("recv server : %s\n", recvBuf);
} else if(len == 0) {
// Indicates that the server is disconnected
printf("server closed...");
break;
}
sleep(1);
}
// Close the connection
close(fd);
return 0;
}
Run a screenshot :
Multithreaded concurrent server
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
struct sockInfo {
int fd; // File descriptor for communication
struct sockaddr_in addr;
pthread_t tid; // Thread number
};
struct sockInfo sockinfos[128];
void * working(void * arg) {
// The sub thread communicates with the client cfd Client information Thread number
// Get client information
struct sockInfo * pinfo = (struct sockInfo *)arg;
char cliIp[16];
inet_ntop(AF_INET, &pinfo->addr.sin_addr.s_addr, cliIp, sizeof(cliIp));
unsigned short cliPort = ntohs(pinfo->addr.sin_port);
printf("client ip is : %s, prot is %d\n", cliIp, cliPort);
// Receive data from client
char recvBuf[1024];
while(1) {
int len = read(pinfo->fd, &recvBuf, sizeof(recvBuf));
if(len == -1) {
perror("read");
exit(-1);
}else if(len > 0) {
printf("recv client : %s\n", recvBuf);
} else if(len == 0) {
printf("client closed....\n");
break;
}
write(pinfo->fd, recvBuf, strlen(recvBuf) + 1);
}
close(pinfo->fd);
return NULL;
}
int main() {
// establish socket
int lfd = socket(PF_INET, SOCK_STREAM, 0);
if(lfd == -1){
perror("socket");
exit(-1);
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(9999);
saddr.sin_addr.s_addr = INADDR_ANY;
// binding
int ret = bind(lfd,(struct sockaddr *)&saddr, sizeof(saddr));
if(ret == -1) {
perror("bind");
exit(-1);
}
// monitor
ret = listen(lfd, 128);
if(ret == -1) {
perror("listen");
exit(-1);
}
// Initialization data
int max = sizeof(sockinfos) / sizeof(sockinfos[0]);
for(int i = 0; i < max; i++) {
bzero(&sockinfos[i], sizeof(sockinfos[i]));
sockinfos[i].fd = -1;
sockinfos[i].tid = -1;
}
// Loop waiting for client connection , Once a client connects in , Just create a child thread to communicate
while(1) {
struct sockaddr_in cliaddr;
int len = sizeof(cliaddr);
// Accept the connection
int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &len);
struct sockInfo * pinfo;
for(int i = 0; i < max; i++) {
// Find a usable... From this array sockInfo Elements
if(sockinfos[i].fd == -1) {
pinfo = &sockinfos[i];
break;
}
if(i == max - 1) {
sleep(1);
i--;
}
}
pinfo->fd = cfd;
memcpy(&pinfo->addr, &cliaddr, len);// take cliaddr copy to addr;
// Create child threads
pthread_create(&pinfo->tid, NULL, working, pinfo);
pthread_detach(pinfo->tid);// Thread recycling is not blocked ;
}
close(lfd);
return 0;
}
4.23TCP State transition
Three handshakes : Both sides established State to establish a connection
边栏推荐
- US stock listing of polar: how can the delivery of 55000 units support the valuation of more than 20billion US dollars
- [engine development] in depth GPU and rendering optimization (basic)
- 提高效率 Or 增加成本,开发人员应如何理解结对编程?
- 复合类型(自定义类型)
- Tonybot humanoid robot checks the port and corresponds to port 0701
- [opengl] geometry shader
- [qingniaochangping campus of Peking University] in the Internet industry, which positions are more popular as they get older?
- 牛客 BM83 字符串變形(大小寫轉換,字符串反轉,字符串替換)
- Luogu p5536 [xr-3] core city solution
- mmdetection 学习率与batch_size关系
猜你喜欢
How to query the baby category of tmall on Taobao
How to color ordinary landscape photos, PS tutorial
复合类型(自定义类型)
提高效率 Or 增加成本,开发人员应如何理解结对编程?
Amazon, express, lazada, shopee, eBay, wish, Wal Mart, Alibaba international, meikeduo and other cross-border e-commerce platforms evaluate how Ziyang account can seize traffic by using products in th
tonybot 人形机器人 首次开机 0630
Protobuf and grpc
Showmebug entered Tencent conference, opening the era of professional technical interview
Use of form text box (I) select text
基因家族特征分析 - 染色体定位分析
随机推荐
[graphics] efficient target deformation animation based on OpenGL es 3.0
Bibit pharmaceutical rushed to the scientific innovation board: annual revenue of 970000, loss of 137million, proposed to raise 2billion
Dllexport et dllimport
分布式事务(Seata) 四大模式详解
[qingniaochangping campus of Peking University] in the Internet industry, which positions are more popular as they get older?
洛谷P3065 [USACO12DEC]First! G 题解
NOI OPENJUDGE 1.3(06)
Zzuli:1042 sum of sequence 3
Zzuli:1054 monkeys eat peaches
Zzuli:1043 max
Paper sharing: generating playful palettes from images
关于敏捷的一些概念
Sub GHz wireless solution Z-Wave 800 Series zg23 SOC and zgm230s modules
Zzuli: cumulative sum of 1050 factorials
C language memory function
7-3 rental (20 points)
[graphics] adaptive shadow map
Zzuli:1056 lucky numbers
dllexport和dllimport
tonybot 人形机器人 红外遥控玩法 0630