当前位置:网站首页>Implement a server with multi process concurrency
Implement a server with multi process concurrency
2022-07-02 14:37:00 【Kallou】
Project source : Sign in — major IT Written interview preparation platform _ Cattle from
This course teaches how to use socket API Implement a TCP Multi process concurrent server of the Protocol . Before implementing the server , First of all, let's get to know TCP The process of communication and the various API.
1.TCP Communication process
TCP In communication , The end that initiates the connection request is called the client , The end that passively accepts the connection is called the server .
Server side :
1. establish A monitor Socket
- monitor : Listen for client connections
- Socket : One socket File descriptor ……socket()
2. Put the File descriptor And local IP And port binding ( Binding socket Address information )……bind()
- This is what the client uses when connecting to the server IP And port
3. Set listening , Listen for the file descriptor to start working ( client socket File to server socket The read buffer of the file sends data , Server side socket Is to monitor whether there is data in your read buffer , The process is carried out by OS complete )……listen()
- Monitoring itself does not accept requests , If you find a connection in the buffer, you will go to the next step
4. Block waiting , until Client initiates connection , After receiving the client connection, a Another one is used to communicate with clients socket……accept()
5. signal communication .……Window:recv()/send() Linux:read()/write()
6. End of communication , close Connect .……close()
Why launch another after listening to the request socket For communicating with clients ?
Suppose that there are two clients that successively initiate a connection and use the same socket Accept connections and communicate , After accepting the first client connection socket Start communicating , At this time, the second client also sent a request ,socket If you accept the request here, you have to communicate with two clients at the same time , and socket Only the address information of one client can be recorded in the file , Isn't that a mess . Therefore, you must accept the connected socket And... For communication socket Distinguish , Use one socket Specifically accept connections , You can create as many connections as you want socket Communicate with .
It also shows TCP Connection oriented features , That is, communication can only be one-to-one , One socket Corresponding to one socket.
client :
1. establish A for communication Socket .( Port number from os Automatically assigned )……socket()
2. Connect to server , It is necessary to formulate the destination server IP And port ……connect()
3. Successful connection , communicate ……send()
4. End of communication , disconnect ……close()
2.socket API
all socket API Need to import header file #include<arpa/inet.h>
- socket()
int socket(int domain, int type, int protocol);
Parameters :
-domain: Specify the address protocol family .
Common values :AF_INET(IPv4),AF_INET6(IPv6)
-type: The type of protocol used in communication .
Common values :SOCK_STREAM( Streaming Protocol ),SOCK_DGRAM( Declarative agreement )
-protocol: Specific protocols used .
General writing 0,os It will be automatically derived according to the first two values .
Return value :
success : Returns the socket file descriptor
Failure :-1
Here, the return file descriptor explains again socket The essence of is document . So just create socket, You can use its returned file descriptor in other functions , Operate like a file socket 了 . In fact, other functions do this .
- bind()
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
Parameters :
-sockfd: jointed socket File descriptor .
-addr: Server process socket Information
Here formal parameters are used struct sockaddr* type , The actual arguments passed in are generally not of this type , Type conversion required
-addrlen:addr The length of
Return value :
Failure :-1
- listen()
int listen(int sockfd, int backlog);
Parameters :
-sockfd: ditto
-backlog: Request queue length
A server process may receive multiple client requests , Before the last request is completed, the new request will be put into the buffer of a queue structure , This buffer is called the request queue .
Return value :
Failure :-1
- accept()
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
Parameters :
-sockfd: ditto
-addr: Used to return to the client socket Address information
-addrlen:addr The length of
Return value :
success : Back to a new socket File descriptor , This file descriptor is used with addr The indicated client communicates
Failure :-1
- connect()
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
Parameters : Same as bind()
Return value :
success :0
Failure :-1
- write()、read()
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);
Parameters :
-fd: communicational socket File descriptor
-buf: To write / Reading data .write Write data to the write buffer ,read Get data from the read buffer
-count:buf length
3. Code example of multiple concurrent servers
This sample program demonstrates an echo client , That is, the client enters a piece of data , The server returns the same data .
Every time the server accepts a connection , Just print the connected client ip And port number .
Multiple clients can access at the same time , The server will create multiple sub processes to request new for each client socket Maintain communication .
Server side :server_process.c
//TCP Communication multiple concurrent server
#include<stdio.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main()
{
// establish socket
int lfd = socket(AF_INET,SOCK_STREAM,0);
if(lfd == -1){
perror("socket");
exit(-1);
}
// binding
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(9999);
saddr.sin_addr.s_addr = INADDR_ANY;
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);
}
// Loop waiting for client connection
while(1){
struct sockaddr_in cliaddr;
int len = sizeof(cliaddr);
// Accept the connection
int cfd = accept(lfd,(struct sockaddr*)&cliaddr,&len);
if(cfd == -1){
perror("accept");
exit(-1);
}
// Enter every connection , Then create a sub process to communicate with the client
pid_t pid = fork();
if(pid == 0){
// Subprocess created successfully
// 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,port is %d\n",cliIP,cliPort);
// Receive data from client
char recvBuf[1024] = {0};
while(1){
int len = read(cfd,&recvBuf,sizeof(recvBuf));
if(len == -1){
perror("read");
exit(-1);
}else if(len > 0){
printf("recv client data : %s\n",recvBuf);
}else{
printf("client closed...");
}
/*
The third parameter +1 Is to bring the newline character in the returned character ,
Otherwise, if the length of the string sent twice is different , May return to
Last left character
*/
write(cfd,recvBuf,strlen(recvBuf)+1);
}
close(cfd);
exit(0);
}
}
close(lfd);
return 0;
}
client :client.c
// 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.59.129",&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
int mnum = 10;
char recvBuf[1024] = {0};
while(mnum > 0)
{
// The client sends data to the server
char * data;
printf("Input:");
scanf("%s",data);
write(fd,data,strlen(data)+1);// Same as the server write The function is the same , Here to +1 Pass newline
//sleep(1);
// Read the data sent by the server
int len = read(fd,recvBuf,sizeof(recvBuf));
if(len == -1)
{
perror("read");
exit(-1);
}else if(len > 0){// Indicates that data has been obtained ,len Is the length of the acquired data
printf("recv server data: %s\n",recvBuf);
mnum--;
}else if(len == 0){// Indicates that the server is disconnected
printf("server closed...\n");
break;
}
}
//4. Close the connection
close(fd);
return 0;
}
边栏推荐
- 腾讯云 TStor 统一存储通过信通院首批文件存储基础能力评测
- Understanding of mongodb
- Solve the problem that openocd fails to burn STM32 and cannot connect through SWD
- 途家木鸟美团夏日折扣对垒,门槛低就一定香吗?
- How many knowledge points can a callable interface have?
- Contrôleur pour threejs cube Space Basic Controller + Inertial Control + Flight Control
- 跨服务器数据访问的创建链接服务器方法
- 4. Array pointer and pointer array
- Xilinx Vivado set *. svh as SystemVerilog Header
- HMS core machine learning service helps zaful users to shop conveniently
猜你喜欢
Daily learning 2
Federated Search: all requirements in search
提示:SQL Server 阻止了对组件‘Ad Hoc Distributed Queries ‘的STATEMENT ‘OpenRowset/OpenDatasource“”
Development and design of animation surrounding mall sales website based on php+mysql
【空间&单细胞组学】第1期:单细胞结合空间转录组研究PDAC肿瘤微环境
每日学习3
[development environment] Dell computer system reinstallation (download Dell OS recovery tool | use Dell OS recovery tool to make USB flash disk system | install system)
Fabric.js 橡皮擦的用法(包含恢复功能)
HMS core machine learning service helps zaful users to shop conveniently
Default slot, named slot, scope slot
随机推荐
Fabric.js 手动加粗文本iText
buuctf-pwn write-ups (7)
fatal: unsafe repository is owned by someone else 的解决方法
Fabric. Keep the original level when JS element is selected
Solving the longest subsequence with linear DP -- three questions
2、const 型指针
提示:SQL Server 阻止了对组件‘Ad Hoc Distributed Queries ‘的STATEMENT ‘OpenRowset/OpenDatasource“”
[Hongke technology sharing] how to test DNS server: DNS performance and response time test
Use of swagger
《可供方案开发》口算训练机/数学宝/儿童口算宝/智能数学宝 LCD液晶显示驱动IC-VK1622(LQFP64封装),原厂技术支持
OpenCV调用USB摄像头的点滴
Yyds dry goods inventory software encryption lock function
docker mysql
Convolutional neural network (Introduction)
threejs的控制器 立方體空間 基本控制器+慣性控制+飛行控制
freemarker的使用
Tujia muniao meituan has a discount match in summer. Will it be fragrant if the threshold is low?
PHP linked list creation and traversal
Yolov3 & yolov5 output result description
4、数组指针和指针数组