当前位置:网站首页>Network high concurrency
Network high concurrency
2022-06-30 04:26:00 【Tra220123】
1. Use multiple processes to process multiple processes concurrently client request
Web servers usually use fork To serve multiple clients at the same time , The parent process is specifically responsible for listening to the port , Every time accept A new client connection is fork A sub process is set up to serve this client .
But when the child process exits, a zombie process will occur , The parent process should pay attention to handling SIGCHLD Signals and calls wait Clean up the zombie process .

If you connect one client at a time , Create a new process , Then the operation is finished , Just end the subprocess , It's too much trouble , And the system costs a lot .
So we can use threads , Compared to the process , Much lighter .

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <pthread.h>
#define SERV_PORT 8000
#define MAXLINE 80
#define prrexit(msg) perror(msg); exit(1);
void *up_server(void *arg) {
int connfd = (int)arg;
char buf[MAXLINE];
pthread_detach(pthread_self());
// Multithreading
pthread_t tid;
pthread_create(&tid, NULL, up_server, (void *)connfd);
printf("new thread is %#lx\n", tid);
while (1) {
int n = read(connfd, buf, MAXLINE);
if (!strncmp(buf, "quit", 4)) break;
write(1, buf, n);
for (int i = 0; i < n; i++) {
buf[i] = toupper(buf[i]);
}
write(connfd, buf, n);
}
close(connfd);
return (void *)0;
}
int main(void) {
struct sockaddr_in serveraddr, clientaddr;
int listenfd, connfd;
socklen_t clientaddr_len;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) prrexit("socket");
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERV_PORT);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) prrexit("bind");
if (listen(listenfd, 3) < 0) prrexit("listend");
printf("Accepting connections...\n");
while (1) {
clientaddr_len = sizeof(clientaddr);
connfd = accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
if (connfd < 0) prrexit("accept");
printf("Received from %s:%d\n", inet_ntop(AF_INET, &clientaddr.sin_addr, str, sizeof(str)), ntohs(clientaddr.sin_port));
/*pid_t pid = fork();
if (pid < 0) prrexit("fork");
if (pid > 0) {
close(connfd);
while (waitpid(-1, NULL, WNOHANG) > 0) {}
continue;
}
close(listenfd);*/
while (1) {
int n = read(connfd, buf, MAXLINE);
if (!strncmp(buf, "quit", 4)) break;
write(1, buf, n);
for (int i = 0; i < n; i++) {
buf[i] = toupper(buf[i]);
}
write(connfd, buf, n);
}
close(connfd);
}
return 0;
}2. be based on UDP Protocol network program
UDP client / Server communication process :

server:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <pthread.h>
#define SERV_PORT 8000
#define MAXLINE 80
#define prrexit(msg) perror(msg); exit(1);
int main(void) {
int sockfd;
struct sockaddr_in servaddr, cliaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
printf("udpserver ready~\n");
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
socklen_t cliaddr_len;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
while (1) {
int n = recvfrom(sockfd, buf, MAXLINE, 0, (struct sockaddr *)&cliaddr, &cliaddr_len);
if (n < 0) prrexit("recvfrom");
printf("receive from %s:%d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
for (int i = 0; i < n; i++) {
buf[i] = toupper(buf[i]);
}
sendto(sockfd, buf, MAXLINE, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
}
close(sockfd);
return 0;
}client:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <string.h>
#define SERV_PORT 8000
#define MAXLINE 80
int main(void) {
struct sockaddr_in servaddr;
char buf[MAXLINE];
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
int n;
while(n = read(sockfd, buf, MAXLINE)) {
n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
write(1, buf, n);
}
close(sockfd);
return 0;
}3. Use thread pool for concurrent processing
Many thread pools can be created to compete for client service tasks and perform operations .
Thread pool : All threads to grab resources .
4. Use epoll+ The thread pool processes multiple threads concurrently
epoll: By registering callback Function mode , When a file descriptor sends a change , Will take the initiative to inform .

server:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/epoll.h>
#define SERV_PORT 8000
#define MAXLINE 80
#define prrexit(msg) perror(msg); exit(1);
typedef struct Task
{
int fd;
struct Task *next;
}Task;
typedef struct Task_pool {
Task *head;
Task *tail;
pthread_mutex_t lock;
pthread_cond_t havetask;
}Task_pool;
Task_pool *task_pool_init() {
Task_pool *tp = (Task_pool *)malloc(sizeof(Task_pool));
tp->head = NULL;
tp->tail = NULL;
pthread_mutex_init(&tp->lock, NULL);
pthread_cond_init(&tp->havetask, NULL);
return tp;
}
void task_pool_push(Task_pool *tp, int fd) {
pthread_mutex_lock(&tp->lock);
Task *t = (Task *)malloc(sizeof(Task));
t->fd = fd;
t->next = NULL;
if (!tp->tail) {
tp->head = tp->tail = t;
} else {
tp->tail->next = t;
tp->tail = t;
}
pthread_cond_broadcast(&tp->havetask);
pthread_mutex_unlock(&tp->lock);
}
Task task_pool_pop(Task_pool *tp) {
pthread_mutex_lock(&tp->lock);
while (tp->head == NULL) {
pthread_cond_wait(&tp->havetask, &tp->lock);
}
Task tmp, *k;
k = tp->head;
tmp = *k;
tp->head = tp->head->next;
if (!tp->head) tp->tail = NULL;
free(k);
pthread_mutex_unlock(&tp->lock);
return tmp;
}
void task_pool_free(Task_pool *tp) {
pthread_mutex_lock(&tp->lock);
Task *p = tp->head, *k;
while (p) {
k = p;
p = p->next;
free(k);
}
tp->head = NULL;
pthread_mutex_unlock(&tp->lock);
pthread_mutex_destroy(&tp->lock);
pthread_cond_destroy(&tp->havetask);
free(tp);
return;
}
void *up_server(void *arg) {
pthread_detach(pthread_self());
char buf[MAXLINE];
int n, i;
Task_pool *tp = arg;
while (1) {
Task tmp = task_pool_pop(tp);
int connfd = tmp.fd;
printf("get task fd=%d\n", connfd);
if (1) {
n = read(connfd, buf, MAXLINE);
write(1, buf, n);
for (i = 0; i <n; i++) {
buf[i] = toupper(buf[i]);
}
write(connfd, buf, n);
}
printf("finish task fd=%d\n", connfd);
if (!strncmp(buf, "quit", 4)) {
close(connfd);
}
}
return (void *)0;
}
int main(void) {
int sockfd;
int listenfd, connfd;
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddr_len;
Task_pool *tp = task_pool_init();
// Multithreading
pthread_t tid;
for (int i = 0; i < 4; i++) {
pthread_create(&tid, NULL, up_server, (void *)tp);
printf("new thread is %#lx\n", tid);
}
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) prrexit("socket");
int epfd = epoll_create(256);
struct epoll_event ev, events[256];
// The server IP Address : Port initialization
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) prrexit("bind");
if (listen(listenfd, 2) < 0) prrexit("listen");
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
printf("Accepting connections...\n");
while (1) {
int nfds = epoll_wait(epfd, events, 256, -1);
for (int i = 0; i < nfds; i++) {
if (events[i].data.fd == listenfd) {
cliaddr_len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
if (connfd < 0) prrexit("accept");
printf("receive from %s:%d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listenfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);
//task_pool_push(tp, connfd);
} else if (events[i].events & EPOLLIN) {
int clifd = events[i].data.fd;
if (clifd < 3) continue;
task_pool_push(tp, clifd);
}
}
}
task_pool_free(tp);
return 0;
}5.HTTP agreement
Hypertext transfer protocol (HyperText Trasnsfer Protocol) It's for distributed 、 Application layer protocols for collaborative and hypermedia information systems .
HTTP Is the foundation of data communication in the world wide web .
①HTTP The protocol takes the request / Response model .

② Stateless storage
HTTP It's an unsaved state , Stateless protocol .
HTTP The protocol itself does not report an error in the communication status between the request and the response . stay HTTP This level , The protocol does not persist the sent request or response .

③ There is no connection
Limit one request per connection .
The server completes the client's request , And received the customer's response , disconnect .
In this way, the transmission time can be saved and the concurrency performance can be improved , Unable to establish a long-term connection with each user , Request one response at a time , The server and the client are interrupted .
6.HTTP Request method
HTTP/1.1 Definitions in the agreement 8 Methods ( action ) To operate the specified resources in different ways :
①GET
Send... To the specified resource “ Show ” request .
②POST
Submit data to specified resources , Request server to process ( Such as : Submit forms or upload files ).
③HEAD
And GET equally , All requests to the server for specified resources . But the server will not return the text part of the resource .
④PUT
Upload the latest content to the specified resource location .
⑤DELETE
Request server delete Request-URI Identified resources .
⑥TRACE
Echo requests received by server , Mainly used for testing or diagnosis .
⑦OPTIONS
Enables the server to return all data supported by the resource HTTP Request method .
⑧CONNECT
HTTP/1.1 The protocol is reserved for the proxy server that can change the connection to pipeline mode .
7.HTTP Status code
all HTTP The first line of the response is the status line , In turn is the present HTTP Version number ,3 A status code consisting of digits and a phrase describing the status , Separated from each other by spaces .

8.URL
Hypertext transfer protocol HTTP The uniform resource locator of includes five basic elements of getting information from the Internet in a simple address :

9.HTTP Request format

10. perform CGI Program
If the browser is requesting an executable ( No matter what the executable is , Even if shell The same is true of scripts ), The server does not send the file itself to the browser , Instead, it sends the standard output of its execution results to the browser .
web Browser workflow :
① Parsing browser requests , Find the corresponding file in the service directory , If the file cannot be found, it will return 404 Error page
② If you find the file requested by the browser , use stat(2) Check if it is executable
③ If the file is executable :
a. send out HTTP/1.1 200 OK To the client
b.fork(2), use dup2(2) Redirect the standard output of the child process to the client socket
c. In the subprocess exec(3) The CGI Program
d. Close the connection
④ If the modified file is not executable :
a. send out HTTP/1.1 200 OK To the client
b. If it is a picture file , Send the corresponding... According to the extension of the picture Content-type
c. If it's not a picture file , Simplify , All as Content-Type:text
d. ordinary HTTP These two lines at the head of the agreement are enough , Send another blank line to end
e. Read the contents of the file and send it to the client
f. Close the connection
边栏推荐
- Websocket implementation principle
- 487-3279(POJ1002)
- errno和perror
- MySQL DDL change
- Qt Creator 8 Beta2发布
- 【WEBRTC】ADM: rtc_include_internal_audio_device 触发 RTC_DCHECK(adm) 断言
- Error in conditional filter (if) syntax in sum function in SQL Server2005
- Internship: interface case implementation
- Day 10 data saving and loading
- 工程安全和工程质量
猜你喜欢

Day 11 script and game AI

Share an example of a simple MapReduce method using a virtual machine

I spent three years in a big factory outsourcing, which subverted my understanding!

Day 12 advanced programming techniques

OneNote software

Anonymous pipeline for interprocess communication

Basic knowledge of redis

Cloud native -- websocket of Web real-time communication technology

Matlab reads fig file and restores signal

破局存量客群营销,试一下客户分群管理(含聚类模型等实操效果评估)
随机推荐
Detailed explanation of data link layer
After the win10 system uses the browser to download, the content is moved or deleted without reason
How to use div boxes to simulate line triangles
Create thread in callable mode
FortiGate firewall quick initialization administrator password
JS import and export
Indefinite parameters of JS function
Ora-00907: missing right parenthesis problem supplement
2021-11-04
基于SSM框架茶叶商城系统【项目源码+数据库脚本+报告】
SQLyog导入数据库时报错,求帮解决!
Iterator of JS
Errno and PERROR
SQL追加字段
Knowledge - how to build rapport in sales with 3 simple skills
Collinearity problem
Matlab reads fig file and restores signal
errno和perror
股票利益【非dp】
Threadlocal