当前位置:网站首页>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;
}
边栏推荐
- The use of TestNG, the testing framework (II): the use of TestNG XML
- 3. Function pointers and pointer functions
- socket(套接字)与socket地址
- Fabric. JS free drawing ellipse
- 跨服务器数据访问的创建链接服务器方法
- docker mysql
- Fabric.js 上划线、中划线(删除线)、下划线
- taobao.logistics.dummy.send( 无需物流发货处理 )接口,淘宝店铺发货API接口,淘宝订单发货接口,淘宝r2接口,淘宝oAu2.0接口
- <口算練習機 方案開發原理圖>口算練習機/口算寶/兒童數學寶/兒童計算器 LCD液晶顯示驅動IC-VK1621B,提供技術支持
- Tip: SQL Server blocked the state 'openrowset/opendatasource' of component 'ad hoc distributed queries'
猜你喜欢

Uniapp automated test learning

没有从远程服务器‘‘映射到本地用户‘(null)/sa‘的远程用户‘sa‘及服务主密码解密错误的解决办法

PHP linked list creation and traversal

Makefile separates file names and suffixes

Yolov3 & yolov5 output result description

##51单片机实验之简易验证码发生器

C crystal report printing

The most complete analysis of Flink frame window function

fatal: unsafe repository is owned by someone else 的解决方法

Quick analysis: easy to share the Internet
随机推荐
PTA题库 ===>复数四则运算,一帮一,考试座位号(7-73)
The most complete analysis of Flink frame window function
报错:npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
PyQt5_ Qscrollarea content is saved as a picture
Quarkus learning IV - project development to deployment
Thoroughly master prototype__ proto__、 Relationship before constructor (JS prototype, prototype chain)
Golang quickly generates model and queryset of database tables
富文本编辑器添加矢量公式(MathType for TinyMCE ,可视化添加)
Go operation redis
Teamtalk source code analysis win client
buuctf-pwn write-ups (7)
【apipost】使用教程
taobao. trade. Get (get some information of a single transaction), Taobao store order interface, Taobao oauth2.0 interface, Taobao R2 interface code docking and sharing
检查密码
3、函数指针和指针函数
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 '
QT new project
NLA自然语言分析,让数据分析更智能
Do you know that there is an upper limit on the size of Oracle data files?
fatal: unsafe repository is owned by someone else 的解决方法