当前位置:网站首页>Write a select based concurrent server
Write a select based concurrent server
2022-06-12 18:00:00 【Tao song remains the same】
Hello everyone , I'm brother Tao .
Many readers are interested in network programming , I think it's interesting , I hope I can write more practical examples of network programming . That's all right. , Here we are .
For back-end development students , Must know about multithreaded concurrent servers , So how to play with multiplexed concurrent services ? It will be clear after reading this article .
today , Let's have a real fight based on select The concurrent server of the model , The actual experimental results are given , I hope you can have some new understanding and harvest .
If you don't know , Let me draw it by hand , You'll see :8 A boy pursues a girl , This girl deals with 8 A boy's communication request .

Server implementation
Everyone to select The function should be familiar with , Next , Let's look at the server program , In the key place , There are basically detailed notes :
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int totalSockets = 0; // socket Total of
SOCKET socketArray[100]; // socket Array of components , Suppose there is at most 100 individual socket Well
// Log printing
void log(const char *pStr)
{
FILE *fp = fopen("log.txt", "a");
fprintf(fp, "log:%s\n", pStr);
fclose(fp);
}
// establish socket
void addToSocketArr(SOCKET s)
{
socketArray[totalSockets] = s;
totalSockets++;
}
// Start the server
int main()
{
log("into main");
// Network initialization
WSADATA wsaData;
WSAStartup(MAKEWORD(1, 1), &wsaData);
// establish socket
SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, 0);
addToSocketArr(listenSocket);
// Service location information
SOCKADDR_IN srvAddr;
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
srvAddr.sin_port = htons(8888);
// binding
bind(listenSocket, (SOCKADDR*)&srvAddr, sizeof(srvAddr));
// monitor
listen(listenSocket, 10);
// Set up socket Is non-blocking mode
unsigned long nonBlock = 1;
ioctlsocket(listenSocket, FIONBIO, &nonBlock);
while(1)
{
// Reading collection , Remember to reset initialization
FD_SET readSet;
FD_ZERO(&readSet);
// Each one socket Into the reading set , It is convenient for the kernel to monitor these socket
int i = 0;
for(i = 0; i < totalSockets; i++)
{
FD_SET(socketArray[i], &readSet);
}
// The application notifies the kernel to monitor the data in the read set socket, final NULL Indicates that the timeout is infinitely long
int total = select(0, &readSet, NULL, NULL, NULL);
// We don't think about select Failure , So here's the program , It means that there must be socket be in " Ready state "
for(i = 0; i < totalSockets; i++)
{
char szTmp[20] = {0};
sprintf(szTmp, "%d", i);
log(szTmp);
if(socketArray[i] == listenSocket) // To monitor socket Judge
{
log("socketArray[i] == listenSocket");
if(FD_ISSET(listenSocket, &readSet)) // If it's time to socket In the readable set , It indicates that there is a client to connect
{
log("listenSocket, socketArray[i] == listenSocket");
// Receive from the client connect request
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
SOCKET acceptSocket = 0;
acceptSocket = accept(listenSocket,(SOCKADDR*)&addrClient, &len);
// Set to non-blocking mode
nonBlock = 1;
ioctlsocket(acceptSocket, FIONBIO, &nonBlock);
// Add to socket Array
addToSocketArr(acceptSocket);
}
continue;
}
// Be careful : above listenSocket Is not responsible for communication , Some of the following socket All responsible for communication socket
// If communication socket In read ready state
if (FD_ISSET(socketArray[i], &readSet))
{
log("to receive");
char szRecvBuf[1024] = {0};
recv(socketArray[i], szRecvBuf, sizeof(szRecvBuf) - 1, 0);
printf("socketArray[i] is %d, %s\n", socketArray[i], szRecvBuf);
}
}
}
// Omit closing socket And so on
return 0;
}Compile and run the program , Open server , Waiting for the client to connect .
Client implementation
Next , Let's look at the client program , Is very normal , It's also very concise. :
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(1, 1);
WSAStartup( wVersionRequested, &wsaData );
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(8888);
connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
while(1)
{
char szSendBuf[100] = {0};
scanf("%s", szSendBuf);
send(sockClient, szSendBuf, strlen(szSendBuf) + 1, 0);
}
closesocket(sockClient);
WSACleanup();
return 0;
}The result of actual combat
We compile the above client program , Then run continuously 8 Secondary client , And then there comes 8 Client processes . Please note that , Keep this 8 Both client processes are running , Don't shut them down .
then , stay 8 Enter... In turn from one client process to another 1, 2, 3, 4, 5, 6, 7, 8 after , Press separately Enter send out , Then enter... Again in the first client process 111, And press Enter send out .
Next , Let's take a look at the results of the server :
socketArray[i] is 136, 1
socketArray[i] is 152, 2
socketArray[i] is 164, 3
socketArray[i] is 176, 4
socketArray[i] is 188, 5
socketArray[i] is 200, 6
socketArray[i] is 212, 7
socketArray[i] is 224, 8
socketArray[i] is 136, 111
You can see , The server can communicate with 8 Communicate with multiple clients , And don't confuse them , This is based on select The concurrent server of the model .
in addition , from log.txt As can be seen from my log , Although there are 8 A client , But the monitoring of the server socket Is the only one. , This is also a well understood thing .

It is suggested that interested students actually play this example , Deepen the understanding of multiplex concurrent server , Improve actual combat capability .
Network programming is like this , Set a good idea , More programming , Grab more bags , Multi debugging , Refreshing ! If you have any questions, please leave a message .
边栏推荐
猜你喜欢
![[CSP]202012-2期末预测之最佳阈值](/img/40/9b59bd692bcfe05d16614cc6d55d1f.png)
[CSP]202012-2期末预测之最佳阈值

SSM integrates FreeMarker and common syntax

企业架构的第一性原理

ES7 does not use parent-child and nested relationships to implement one to many functions

A method of quickly reusing wechat login authorization in app

Office application cannot start normally 0xc0000142

Schéma de cristallisation différentielle active et différence entre LV - PECL, LVDS et hcsl

Tensorflow prompts typeerror: unsupported operand type (s) for *: 'float' and 'nonetype‘

Overall flow chart of kernel interrupt

一种好用、易上手的小程序IDE
随机推荐
TypeScript常用类型(一)
JDBC快速入門教程
566. reshaping the matrix
[CSP]202012-2期末预测之最佳阈值
Graphical data model for system design
C brief introduction
机器学习系列(5):朴素贝叶斯
Project training of Software College of Shandong University - Innovation Training - network attack and defense shooting range experimental platform of Software College of Shandong University (XXV) - p
Use applet to quickly generate app in seven steps
Goframe gredis configuration management | comparison of configuration files and configuration methods
极限编程--根源分析实践
Vulnhub[DC3]
js将数组中的0移动到末尾
Leetcode491 increasing subsequence
续2 asp.net core 路由程序基础使用演示0.2 默认控制器数据的获取到
Use of split method of string
Explanation of core interrupt of Godson processor
低代码平台调研结果
vant3+ts+pinia tab选项卡列表页面点击进详情,详情页返回tab高亮在原位置,刷新高亮默认在第一项
Authorization in Golang ProjectUseing Casbin