当前位置:网站首页>Multithreaded high concurrency server: three problems
Multithreaded high concurrency server: three problems
2022-06-29 11:07:00 【Vegetable chicken obsessed with c++】
1. Whether the sub thread can close the listening file descriptor ?
2. Whether the main thread can close the communication file descriptor ?
3. Multiple child threads share cfd, What problems will happen ?
answer 1: You can't , Parent and child threads share file descriptors , If the child process closes the listening file descriptor , Second child thread Accept It's going to go wrong .Accept The first parameter to is the listener file descriptor .
answer 2: You can't , If the main thread closes the communication file descriptor , This will directly cause the server to fail to read , because Read The first parameter to is the communication file descriptor .
answer 3: If multiple clients are connected to the server at the same time , The communication file descriptor will be overwritten , Only the last file descriptor works , Only one client can communicate normally .
terms of settlement : These sub threads are not sharing the same memory , Instead, share an array ( Divide the memory into arrays of appropriate size ), This will not cause the file descriptor to be overwritten .
The specific code is as follows :
// Multithreaded version of the server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <ctype.h>
#include <pthread.h>
#include "wrap.h"
typedef struct info
{
int cfd; // if -1 Means available , Greater than 0 Indicates occupied
int idx;
pthread_t thread;
struct sockaddr_in client;
}INFO;
INFO thInfo[1024];
// Thread execution function
void *thread_work(void *arg)
{
INFO *p = (INFO *)arg;
printf("idx==[%d]\n", p->idx);
char sIP[16];
memset(sIP, 0x00, sizeof(sIP));
printf("new client:[%s][%d]\n", inet_ntop(AF_INET, &(p->client.sin_addr.s_addr), sIP, sizeof(sIP)), ntohs(p->client.sin_port));
int n;
int cfd = p->cfd;
struct sockaddr_in client;
memcpy(&client, &(p->client), sizeof(client));
char buf[1024];
while(1)
{
memset(buf, 0x00, sizeof(buf));
// Reading data
n = Read(cfd, buf, sizeof(buf));
if(n<=0)
{
printf("read error or client closed, n==[%d]\n", n);
Close(cfd);
p->cfd =-1; // Set to -1 Indicates that the location is available
pthread_exit(NULL);
}
for(int i=0; i<n; i++)
{
buf[i] = toupper(buf[i]);
}
// send data
Write(cfd, buf, n);
}
}
void init_thInfo()
{
int i = 0;
for(i=0; i<1024; i++)
{
thInfo[i].cfd = -1;;
}
}
int findIndex()
{
int i;
for(i=0; i<1024; i++)
{
if(thInfo[i].cfd==-1)
{
break;
}
}
if(i==1024)
{
return -1;
}
return i;
}
int main()
{
// establish socket
int lfd = Socket(AF_INET, SOCK_STREAM, 0);
// Set up port multiplexing
int opt = 1;
setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
// binding -- take lfd and IP PORT binding
struct sockaddr_in serv;
bzero(&serv, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(8888);
serv.sin_addr.s_addr = htonl(INADDR_ANY);
Bind(lfd, (struct sockaddr *)&serv, sizeof(serv));
// monitor
Listen(lfd, 128);
// initialization
init_thInfo();
int cfd;
int ret;
int idx;
socklen_t len;
pthread_t thread;
struct sockaddr_in client;
while(1)
{
len = sizeof(client);
bzero(&client, sizeof(client));
// Get a new connection
cfd = Accept(lfd, (struct sockaddr *)&client, &len);
// Create a subprocess , Let the child process handle the connection --- Receiving data and sending data
// Find a free position in the array
idx = findIndex();
if(idx==-1)
{
Close(cfd);
continue;
}
// Assign a value to the member of the element in the free position
thInfo[idx].cfd = cfd;
thInfo[idx].idx = idx;
memcpy(&thInfo[idx].client, &client, sizeof(client));
// Create child threads --- This sub thread completes the sending and receiving of data
ret = pthread_create(&thInfo[idx].thread, NULL, thread_work, &thInfo[idx]);
if(ret!=0)
{
printf("create thread error:[%s]\n", strerror(ret));
exit(-1);
}
// Set the child thread as the separation property
pthread_detach(thInfo[idx].thread);
}
Close(lfd);
return 0;
}Next, test with three clients at the same time :

边栏推荐
- 多线程高并发服务器:3个问题
- Common motor classification and driving principle animation [easy to understand]
- 【C语言进阶】字符串和内存函数(二)
- 【C语言进阶】动态内存管理
- NUC980开源项目16-从SPI FLASH(W25Q128)启动
- Nuc980 open source project 16- start from SPI flash (w25q128)
- Online text filter less than specified length tool
- 每日刷题记录 (七)
- 在编写shell脚本时如何正确姿势地管理临时文件
- math_数学表达式&等式方程的变形&组合操作技巧/手段积累
猜你喜欢

在线SQL转HTMLTable工具

8年打磨,《游戏设计梦工厂》发布史诗级更新!

【数字信号调制】基于 AM+FM+DSB+SSB实现信号调制解调含Matlab源码

ModbusTCP协议网络学习型单路红外模块(双层板)

悬赏平台并没有WEB端开发,在原生开发和混合开发中哪种合适?

【Rust每周一库】Tokei - 统计代码行数等信息的实用工具

【C语言进阶】字符串和内存函数(二)

The last 48 hours! The cloud XR theme competition invites you to bloom together. See you at the competition!

9 款好用到爆的 JSON 处理工具,极大提高效率!

UserWarning: Usage of dash-separated ‘script-dir‘ will not be supported in future versions. note
随机推荐
(JS)迭代器模式
【NLP】文本生成专题1:基础知识
添加通知公告,给在线用户发送通知
极限导论总结
学习通否认 QQ 号被盗与其有关:已报案;iPhone 14 量产工作就绪:四款齐发;简洁优雅的软件早已是明日黄花|极客头条...
[digital signal modulation] realize signal modulation and demodulation based on am+fm+dsb+ssb, including Matlab source code
TTL串口学习型红外遥控模块可扩展成网络控制
活动邀请 | Apache Doris 社区征文&演讲征集活动开始了!
(JS)isNaN()方法判断undefined为true的原因
ModbusTCP协议网络学习型单路红外模块(双层板)
He was in '98. I can't play with him
MySQL query table field information
企业竞争分析的几种方法:SWOT、波特五力、PEST「建议收藏」
《Datawhale推荐系统教程》来了!
【C语言进阶】通讯录实现
CS231n-2022 Module1: 神经网络要点概述(2)
Numeric Keypad
嵌入式驱动开发之uboot---uboot 中的常见命令参数参数
常见电机分类和驱动原理动画[通俗易懂]
NUC980开源项目16-从SPI FLASH(W25Q128)启动