当前位置:网站首页>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;
}
边栏推荐
- 跨服务器数据访问的创建链接服务器方法
- fatal: unsafe repository is owned by someone else 的解决方法
- [Hongke technology sharing] how to test DNS server: DNS performance and response time test
- [apipost] tutorial
- Borui data integrated intelligent observable platform was selected into the "Yunyuan production catalogue" of China Academy of communications in 2022
- 微信小程序使用towxml显示公式
- Threejs controller cube space basic controller + inertia control + flight control
- php链表创建和遍历
- Fabric. JS dynamically set font size
- Fabric. JS zoom canvas
猜你喜欢

Fabric.js 自由绘制圆形

Tencent cloud tstor unified storage passed the evaluation of the first batch of basic file storage capabilities of the ICT Institute

富文本编辑器添加矢量公式(MathType for TinyMCE ,可视化添加)

Fabric. JS upper dash, middle dash (strikethrough), underline

途家木鸟美团夏日折扣对垒,门槛低就一定香吗?

复用和分用

Yolov3 & yolov5 output result description

Actual combat sharing of shutter screen acquisition

天猫商品详情接口(APP,H5端)

关于Flink框架窗口(window)函数最全解析
随机推荐
Factal: Unsafe repository is owned by someone else Solution
There is no solution to the decryption error of the remote user 'sa' and the service master password mapped from the remote server 'to the local user' (null) /sa '
STM32 standard firmware library function name (I)
NLA自然语言分析,让数据分析更智能
篇9:XShell免费版安装
Method of creating linked server for cross server data access
富文本编辑器添加矢量公式(MathType for TinyMCE ,可视化添加)
Makefile 分隔文件名与后缀
Talk about idempotent design
Default slot, named slot, scope slot
Analysis of CPU surge in production environment service
Xilinx Vivado set *.svh as SystemVerilog Header
Yolov3 & yolov5 output result description
Methods of software testing
fatal: unsafe repository is owned by someone else 的解决方法
Makefile separates file names and suffixes
NLA natural language analysis makes data analysis more intelligent
uniapp自动化测试学习
[Hongke technology sharing] how to test DNS server: DNS performance and response time test
fatal: unsafe repository is owned by someone else 的解决方法