国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

五、Linux C/C++ 對epoll-reactor服務(wù)器的百萬級高并發(fā)實現(xiàn)

這篇具有很好參考價值的文章主要介紹了五、Linux C/C++ 對epoll-reactor服務(wù)器的百萬級高并發(fā)實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


前言:基于epoll的反應(yīng)堆模式(reactor)的服務(wù)器程序,進行百萬并發(fā)量的連接測試。通過代碼優(yōu)化,以及服務(wù)器與客戶端的硬件配置優(yōu)化,達到百萬并發(fā)。

一、服務(wù)器:epoll-reactor

  • 代碼實現(xiàn)
    #include <iostream>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <string.h>
    #include <sys/poll.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/epoll.h>
    #include <sys/time.h>
    
    using namespace std;
    
    #define TIME_SUB_MS(tv1, tv2)  ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)
    struct timeval tv_last;
    
    #define BUFFER_LEN 512
    #define CLIENT_MAX_COUNT 1048576
    typedef int (*EPOLL_CALLBACK)(int fd);
    struct CONNECT_ITEM {
    	char rBuffer[BUFFER_LEN] = {0};
    	int rLen = 0;
    	char wBuffer[BUFFER_LEN] = {0};
    	int wLen = 0;
    
    	union {
    		EPOLL_CALLBACK accept_callback = nullptr;
    		EPOLL_CALLBACK recv_callback;
    	}recv_t;
    	EPOLL_CALLBACK send_callback = nullptr;
    }connect_item[CLIENT_MAX_COUNT];
    
    int epfd = 0;
    
    enum _EPOLL_CTRL{
    	ADD,
    	MOD
    };
    
    void setEvent(int fd, EPOLL_EVENTS events, _EPOLL_CTRL ctrl) {
    	epoll_event ev;
    	ev.events = events; //默認水平觸發(fā)(LT),有(數(shù)據(jù))事件就會一直觸發(fā),知道全部處理完
    	/*
    		EPOLLET為邊沿觸發(fā)(ET),當有事件發(fā)生時只觸發(fā)一次,
    		比如來數(shù)據(jù)了,如果一次沒有讀完,不會再觸發(fā)了,所以必須全部讀完,在進行下一次epoll_wait
    	*/
    	//ev.events = EPOLLIN | EPOLLET;
    	ev.data.fd = fd;
    	epoll_ctl(epfd, ctrl == ADD ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ev);
    }
    
    int recv_cb(int fd) {
    	char* buffer = connect_item[fd].rBuffer;
    	int index = connect_item[fd].rLen;
    
    	int count = recv(fd, buffer + index, BUFFER_LEN - index, 0);
    	
    	if (count == 0) {
    		//printf("disconnect: %d\n", fd);
    
    		epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);		
    		close(fd);
    		
    		return count;
    	}else if (count < 0) {
    		//printf("error\n");
    
    		return count;
    	}
    
    	connect_item[fd].rLen += count; //這里的rLen可能會超出buffer的大小,這里就不做處理了
    	//printf("RECV===>>> clientfd: %d, count: %d, buffer: %s\n", fd, count, buffer);
    
    	//改變該文件描述符的事件類型為EPOLLOUT
    	setEvent(fd, EPOLLOUT, MOD);
    
    	//發(fā)送buffer賦值
    	memcpy(connect_item[fd].wBuffer, connect_item[fd].rBuffer, connect_item[fd].rLen);
    	connect_item[fd].wLen = connect_item[fd].rLen;
    
    	//發(fā)送了多少,代表處理了多少
    	connect_item[fd].rLen -= connect_item[fd].wLen;
    	
    	return count;
    }
    
    int send_cb(int fd) {
    	char* buffer = connect_item[fd].wBuffer;
    	int index = connect_item[fd].wLen;
    	
    	int count = send(fd, buffer, connect_item[fd].wLen, 0);
    
    	//改變該文件描述符的事件類型為EPOLLIN
    	setEvent(fd, EPOLLIN, MOD);
    
    	return count;
    }
    
    int accept_cb(int fd) {
    	struct sockaddr_in clientaddr;
    	socklen_t len = sizeof(clientaddr);
    	
    	int clientfd = accept(fd, (struct sockaddr*)&clientaddr, &len);
    
    	setEvent(clientfd, EPOLLIN, ADD);
    
    	memset(connect_item[clientfd].rBuffer, 0, sizeof(connect_item[clientfd].rBuffer));
    	connect_item[clientfd].rLen = 0;
    	memset(connect_item[clientfd].wBuffer, 0, sizeof(connect_item[clientfd].wBuffer));
    	connect_item[clientfd].wLen = 0;
    	connect_item[clientfd].recv_t.recv_callback = recv_cb;
    	connect_item[clientfd].send_callback = send_cb;
    	
    	//printf("ACCEPT===>>> clientfd:%d\n", clientfd);
    
    	if (clientfd % 1000 == 999) {
    		struct timeval tv_cur;
    		gettimeofday(&tv_cur, NULL);
    		printf("clientfd: %d, time_used: %d\n", clientfd, int(TIME_SUB_MS(tv_cur, tv_last)));
    
    		tv_last = tv_cur;
    	}
    
    	return clientfd;
    }
    
    int init_server(int port) {
    	int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    
        sockaddr_in serverAddr;
        memset(&serverAddr, 0, sizeof(serverAddr));
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        serverAddr.sin_port = htons(port);
        bind(listenfd, (sockaddr*)&serverAddr, sizeof(serverAddr));
    
        listen(listenfd, 10);
    
    	return listenfd;
    }
    
    int main() {
        epfd = epoll_create(1); // int size
    	
    	gettimeofday(&tv_last, NULL);
    
    	for (int i = 0; i < 20; i++) {
    		int listenfd = init_server(2048 + i);
    
    		connect_item[listenfd].recv_t.accept_callback = accept_cb;
    		setEvent(listenfd, EPOLLIN, ADD);
    	}
    
    	struct epoll_event events[100000] = {0};
    	while (1) {
    		int nready = epoll_wait(epfd, events, 100000, -1);
    
    		for (int i = 0; i < nready; i++) {
    			int connfd = events[i].data.fd;
    
    		    if (events[i].events & EPOLLIN) {
    				int count = connect_item[connfd].recv_t.recv_callback(connfd);
    			}else if (events[i].events & EPOLLOUT) {
    				connect_item[connfd].send_callback(connfd);
    			}
    		}
    	}
    
    	for (int i = 0; i < 20; i++) {
        	close(i + 3);
    	}
    
        return 0;
    }
    

二、客戶端:multi_port_client_epoll

  • 代碼實現(xiàn):
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/epoll.h>
    #include <errno.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <fcntl.h>
    #include <sys/time.h>
    #include <unistd.h>
    
    
    #define MAX_BUFFER		128
    #define MAX_EPOLLSIZE	(384*1024)
    #define MAX_PORT		20
    
    #define TIME_SUB_MS(tv1, tv2)  ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)
    
    int isContinue = 0;
    
    static int ntySetNonblock(int fd) {
    	int flags;
    
    	flags = fcntl(fd, F_GETFL, 0);
    	if (flags < 0) return flags;
    	flags |= O_NONBLOCK;
    	if (fcntl(fd, F_SETFL, flags) < 0) return -1;
    	return 0;
    }
    
    static int ntySetReUseAddr(int fd) {
    	int reuse = 1;
    	return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
    }
    
    
    
    int main(int argc, char **argv) {
    	if (argc <= 2) {
    		printf("Usage: %s ip port\n", argv[0]);
    		exit(0);
    	}
    
    	const char *ip = argv[1];
    	int port = atoi(argv[2]);
    	int connections = 0;
    	char buffer[128] = {0};
    	int i = 0, index = 0;
    
    	struct epoll_event events[MAX_EPOLLSIZE];
    	
    	int epoll_fd = epoll_create(MAX_EPOLLSIZE);
    	
    	strcpy(buffer, " Data From MulClient\n");
    		
    	struct sockaddr_in addr;
    	memset(&addr, 0, sizeof(struct sockaddr_in));
    	
    	addr.sin_family = AF_INET;
    	addr.sin_addr.s_addr = inet_addr(ip);
    
    	struct timeval tv_begin;
    	gettimeofday(&tv_begin, NULL);
    
    	while (1) {
    		if (++index >= MAX_PORT) index = 0;
    		
    		struct epoll_event ev;
    		int sockfd = 0;
    
    		if (connections < 340000 && !isContinue) {
    			sockfd = socket(AF_INET, SOCK_STREAM, 0);
    			if (sockfd == -1) {
    				perror("socket");
    				goto err;
    			}
    
    			//ntySetReUseAddr(sockfd);
    			addr.sin_port = htons(port+index);
    
    			if (connect(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0) {
    				perror("connect");
    				goto err;
    			}
    			ntySetNonblock(sockfd);
    			ntySetReUseAddr(sockfd);
    
    			sprintf(buffer, "Hello Server: client --> %d\n", sockfd);
    			send(sockfd, buffer, strlen(buffer), 0);
    
    			ev.data.fd = sockfd;
    			ev.events = EPOLLIN | EPOLLOUT;
    			epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sockfd, &ev);
    		
    			connections++;
    		}
    		//connections ++;
    		if (connections % 1000 == 999 || connections >= 340000) {
    			struct timeval tv_cur;
    			memcpy(&tv_cur, &tv_begin, sizeof(struct timeval));
    			
    			gettimeofday(&tv_begin, NULL);
    
    			int time_used = TIME_SUB_MS(tv_begin, tv_cur);
    			printf("connections: %d, sockfd:%d, time_used:%d\n", connections, sockfd, time_used);
    
    			int nfds = epoll_wait(epoll_fd, events, connections, 100);
    			for (i = 0;i < nfds;i ++) {
    				int clientfd = events[i].data.fd;
    
    				if (events[i].events & EPOLLOUT) {
    					//sprintf(buffer, "data from %d\n", clientfd);
    					//send(clientfd, buffer, strlen(buffer), 0);
    					//printf("send:%s\n", buffer);
    				}
    				
    				if (events[i].events & EPOLLIN) {
    					char rBuffer[MAX_BUFFER] = {0};				
    					ssize_t length = recv(clientfd, rBuffer, MAX_BUFFER, 0);
    					if (length > 0) {
    						//printf(" RecvBuffer:%s\n", rBuffer);
    
    						if (!strcmp(rBuffer, "quit")) {
    							isContinue = 0;
    						}
    						
    					} else if (length == 0) {
    						printf(" Disconnect clientfd:%d\n", clientfd);
    						connections --;
    						close(clientfd);
    					} else {
    						if (errno == EINTR) continue;
    
    						printf(" Error clientfd:%d, errno:%d\n", clientfd, errno);
    						close(clientfd);
    					}
    				}
    				
    				// else {
    				// 	printf(" clientfd:%d, errno:%d\n", clientfd, errno);
    				// 	close(clientfd);
    				// }
    			}
    		}
    
    		usleep(10);
    	}
    
    	return 0;
    
    err:
    	printf("error : %s\n", strerror(errno));
    	return 0;
    }
    

三、百萬并發(fā)測試過程

1、硬件配置

  • 1臺服務(wù)器:8G運行內(nèi)存 8核CPU
  • 3臺客戶端:4G運行內(nèi)存 4核CPU

這些硬件配置可以通過虛擬機配置。

按照客戶端測試用例代碼的實現(xiàn),一臺客戶端最大可以創(chuàng)建340000個連接,而一臺電腦的端口最多有65535個,一個端口建立一個連接,除去系統(tǒng)用的前1024個端口,我們可用的也最多只有65535-1024 = 64511個連接,而我們的客戶端代碼之所以能達到340000個連接,這是因為在tcp協(xié)議中的四元組概念,即(源IP,源port,目的IP,目的port),這個四元組構(gòu)成一個tcp連接,只要四元組中的任何一個參數(shù)不同那么就是一個完全不同的連接,因此在源IP與目的IP都固定的情況下,我們從端口來入手,突破65535的限制,我們可以在服務(wù)端創(chuàng)建多個監(jiān)聽socket,分別綁定不同的端口,比如創(chuàng)建了20個監(jiān)聽socket,分別綁定在2048 ~ 2067端口,此時客戶端就可以循環(huán)綁定這20個端口了,客戶端的1個端口就可以在四元組里與服務(wù)端建立20個連接(這是因為服務(wù)端的目的port有20個),而客戶端有1025 ~ 65535的端口可供應(yīng)用程序使用,因此理論上就能建立(65535-1025) x 20 = 1290200個連接,已經(jīng)超超過了百萬,只不過我們的客戶端代碼限定了最大340000個連接。

三臺客戶端就可以實現(xiàn)百萬級并發(fā)測試。我們接下來只演示一個客戶端的并發(fā)測試,另外兩臺操作一樣。

2、測試流程

(1) 在服務(wù)器上編譯運行 目錄一 的服務(wù)器代碼:

g++ -o epoll-reactor epoll-reactor.cpp
./epoll-reactor

(2) 在客戶端上編譯運行 目錄二 的客戶端代碼:

gcc -o mul_port_client_epoll mul_port_client_epoll.c
./mul_port_client_epoll 192.168.1.20 2048

192.168.1.20 2048 是服務(wù)器的地址與端口(根據(jù)自己的電腦傳入自己的地址)

(3) 運行結(jié)果如圖:
百萬級并發(fā)需要大服務(wù)器嗎,LinuxC/C++,網(wǎng)絡(luò)IO,服務(wù)器,linux,c++,c語言

  • 先看客戶端提示:Too many open files,這是因為系統(tǒng)設(shè)置的最多可打開的文件描述符太少了,通過ulimit -a命令查看open files的限制大小為1024,最多可以打開1024個文件描述符,所以會提示connections只有999個,就報錯了。通過ulimit -n 1048576 將其改為百萬級的可打開的文件描述符個數(shù)(1048576為1024x1024)。如圖:
    百萬級并發(fā)需要大服務(wù)器嗎,LinuxC/C++,網(wǎng)絡(luò)IO,服務(wù)器,linux,c++,c語言
  • 再次在客戶端運行測試用例,服務(wù)端也運行起來:
    百萬級并發(fā)需要大服務(wù)器嗎,LinuxC/C++,網(wǎng)絡(luò)IO,服務(wù)器,linux,c++,c語言
  • 我們發(fā)現(xiàn)客戶端仍然只創(chuàng)建了999個(實際比這多,只是代碼每1000個連接打印一次)連接,就出錯了,不過提示的錯誤不一樣了:Connection refused(連接被拒絕),這是服務(wù)器拒絕了客戶端的連接,我們看服務(wù)器的提示信息:Segmentation fault (core dumped),出現(xiàn)了段錯誤,仔細看代碼沒有內(nèi)存越界的問題,可能也是open files的問題,我們也通過命令ulimit -n 1048576 將其也改為百萬級,再次運行測試:
    百萬級并發(fā)需要大服務(wù)器嗎,LinuxC/C++,網(wǎng)絡(luò)IO,服務(wù)器,linux,c++,c語言
  • 這次達到了19999個連接后,出現(xiàn)了Cannot assign requested address(不能分配請求的地址),這是因為linux系統(tǒng)還有一個參數(shù)限制了我們連接的數(shù)目,在/etc/sysctl.conf文件里有這么一個參數(shù):net.ipv4.ip_local_port_range = 1024 2048,可供應(yīng)用程序使用的端口范圍是1024 ~ 2048,但是為什么客戶端能創(chuàng)建19999個連接才掛掉呢,按照端口范圍最多有2048-1024 = 1024個連接,這是因為我們前面所說到的四元組概念,我們的服務(wù)端提供了20個端口可供客戶端去綁定,因此最多可創(chuàng)建20 x 1024 = 20480個連接,所以客戶端達到了19999個連接后掛掉了。所以我們需要修改客戶端的/etc/sysctl.conf文件里的這個參數(shù)net.ipv4.ip_local_port_range = 1024 65535。修改完成后,執(zhí)行 sudo sysctl -p讓其生效,如圖:
    百萬級并發(fā)需要大服務(wù)器嗎,LinuxC/C++,網(wǎng)絡(luò)IO,服務(wù)器,linux,c++,c語言
  • 如果出現(xiàn)cannot stat /proc/sys/net/nf_conntrack_max: No such file or directory的錯誤,執(zhí)行 sudo modprobe ip_conntrack命令,然后再次執(zhí)行sudo sysctl -p命令,讓其生效。我們再次運行測試:
    百萬級并發(fā)需要大服務(wù)器嗎,LinuxC/C++,網(wǎng)絡(luò)IO,服務(wù)器,linux,c++,c語言
  • 這次客戶端連接數(shù)量達到了62999,然后服務(wù)器掛掉了,廢話不多說,直接給出答案:這是因為客戶端的/etc/sysctl.conf文件里還有一個參數(shù):fs.file-max = 65535,這個參數(shù)代表的是文件描述符的最大值是65535,所以上圖的sockfd只達到了63002(實際比63002多,因為測試用例的代碼沒有打印出來),我們修改fs.file-max = 1048576,保存退出后,再次執(zhí)行sudo sysctl -p命令使其生效。然后我們再次測試,如下圖:如果服務(wù)端再次出現(xiàn)段錯誤,并且客戶端出現(xiàn)連接被拒絕,這是因為服務(wù)端的fs.file-max參數(shù)值沒有被修改,我們也將其修改為1048576。
    百萬級并發(fā)需要大服務(wù)器嗎,LinuxC/C++,網(wǎng)絡(luò)IO,服務(wù)器,linux,c++,c語言
    在這里我提示一點,我在測試的過程中,不小心將fs.file-max改成了1024,改的太小了,以至于系統(tǒng)的任何編輯文件的命令都無法執(zhí)行了,這樣系統(tǒng)就不能用了。但是還有補救辦法:執(zhí)行 echo 65535 > /proc/sys/fs/file-max命令,然后再次打開/etc/sysctl.conf文件修改fs.file-max參數(shù)。

我們再次運行測試:
百萬級并發(fā)需要大服務(wù)器嗎,LinuxC/C++,網(wǎng)絡(luò)IO,服務(wù)器,linux,c++,c語言文章來源地址http://www.zghlxwxcb.cn/news/detail-828223.html

  • 這次終于達到了340000個連接,我們的測試流程到這里也就結(jié)束了,想要達到百萬級并發(fā),我們只需要再準備兩臺電腦作為客戶端,重復(fù)上述的操作即可。

到了這里,關(guān)于五、Linux C/C++ 對epoll-reactor服務(wù)器的百萬級高并發(fā)實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • TCP服務(wù)器的演變過程:使用epoll構(gòu)建reactor網(wǎng)絡(luò)模型實現(xiàn)百萬級并發(fā)(詳細代碼)

    TCP服務(wù)器的演變過程:使用epoll構(gòu)建reactor網(wǎng)絡(luò)模型實現(xiàn)百萬級并發(fā)(詳細代碼)

    手把手教你從0開始編寫TCP服務(wù)器程序,體驗開局一塊磚,大廈全靠壘。 為了避免篇幅過長使讀者感到乏味,對【TCP服務(wù)器的開發(fā)】進行分階段實現(xiàn),一步步進行優(yōu)化升級。 本節(jié),在上一章節(jié)介紹了如何使用epoll開發(fā)高效的服務(wù)器,本節(jié)將介紹使用epoll構(gòu)建reactor網(wǎng)絡(luò)模型,實

    2024年02月01日
    瀏覽(28)
  • Linux多路IO復(fù)用技術(shù)——epoll詳解與一對多服務(wù)器實現(xiàn)

    Linux多路IO復(fù)用技術(shù)——epoll詳解與一對多服務(wù)器實現(xiàn)

    本文詳細介紹了Linux中epoll模型的優(yōu)化原理和使用方法,以及如何利用epoll模型實現(xiàn)簡易的一對多服務(wù)器。通過對epoll模型的優(yōu)化和相關(guān)接口的解釋,幫助讀者理解epoll模型的工作原理和優(yōu)缺點,同時附帶代碼實現(xiàn)和圖解說明。

    2024年02月05日
    瀏覽(25)
  • Linux學(xué)習記錄——??? 高級IO(4)--- Epoll型服務(wù)器(1)

    Linux學(xué)習記錄——??? 高級IO(4)--- Epoll型服務(wù)器(1)

    poll依然需要OS去遍歷所有fd。一個進程去多個特定的文件中等待,只要有一個就緒,就使用select/poll系統(tǒng)調(diào)用,讓操作系統(tǒng)把所有文件遍歷一遍,哪些就緒就加上哪些fd,再返回。一旦文件太多了,遍歷效率就顯而易見地低。epoll是為處理大批量句柄而作了改進的poll,句柄就是

    2024年01月18日
    瀏覽(32)
  • Linux網(wǎng)絡(luò)編程:多路I/O轉(zhuǎn)接服務(wù)器(select poll epoll)

    Linux網(wǎng)絡(luò)編程:多路I/O轉(zhuǎn)接服務(wù)器(select poll epoll)

    文章目錄: 一:select 1.基礎(chǔ)API? select函數(shù) 思路分析 select優(yōu)缺點 2.server.c 3.client.c 二:poll 1.基礎(chǔ)API? poll函數(shù)? poll優(yōu)缺點 read函數(shù)返回值 突破1024 文件描述符限制 2.server.c 3.client.c 三:epoll 1.基礎(chǔ)API epoll_create創(chuàng)建? ?epoll_ctl操作? epoll_wait阻塞 epoll實現(xiàn)多路IO轉(zhuǎn)接思路 epoll優(yōu)缺點

    2024年02月11日
    瀏覽(20)
  • day-08 基于Linux的網(wǎng)絡(luò)編程(套接字和標準I/O、分離I/O流、epoll、多線程服務(wù)器)

    標準I/O函數(shù)(stdio)是在C語言中用于進行輸入和輸出操作的庫函數(shù) 。它們包括了一組標準的輸入和輸出函數(shù),如printf、scanf、fopen、fclose等。標準I/O函數(shù)具有以下優(yōu)點: 簡單易用 :標準I/O函數(shù)提供了簡潔的接口,使得輸入和輸出操作變得簡單易用。開發(fā)人員無需自行處理底層

    2024年02月09日
    瀏覽(89)
  • epoll實現(xiàn)并發(fā)服務(wù)器

    epoll 是Linux操作系統(tǒng)提供的一種事件通知機制,用于高效處理大量文件描述符上的事件。它是一種基于內(nèi)核的I/O事件通知接口,可以用于實現(xiàn)高性能的并發(fā)服務(wù)器和異步I/O操作。 與傳統(tǒng)的事件通知機制(如 select 和 poll )相比, epoll 具有更高的性能和擴展性。它采用了一種基

    2024年02月09日
    瀏覽(28)
  • 服務(wù)器IO復(fù)用reactor模式

    調(diào)試: Linux下nc命令作為客戶端: nc 127.0.0.1 7777

    2024年02月10日
    瀏覽(16)
  • epoll并發(fā)服務(wù)器的實現(xiàn)

    epoll并發(fā)服務(wù)器的實現(xiàn)

    1.實現(xiàn)并發(fā)通信的三種方式 ? 實現(xiàn)并發(fā)通信主要有三種方式: 多進程服務(wù)器 、 多路復(fù)用服務(wù)器 (I/O復(fù)用)、 多線程服務(wù)器 多進程服務(wù)器 ? 多進程服務(wù)器指的是利用不同進程處理來自不同客戶端發(fā)來的連接請求,進程之間以輪轉(zhuǎn)的方式運行,由于各個進程之間輪轉(zhuǎn)運行的時

    2024年02月03日
    瀏覽(27)
  • epoll多路復(fù)用_并發(fā)服務(wù)器

    應(yīng)用程序: 驅(qū)動程序:

    2024年02月15日
    瀏覽(19)
  • 【網(wǎng)絡(luò)進階】服務(wù)器模型Reactor與Proactor

    【網(wǎng)絡(luò)進階】服務(wù)器模型Reactor與Proactor

    在高并發(fā)編程和網(wǎng)絡(luò)連接的消息處理中,通??煞譃閮蓚€階段:等待消息就緒和消息處理。當使用默認的阻塞套接字時(例如每個線程專門處理一個連接),這兩個階段往往是合并的。因此,處理套接字的線程需要等待消息就緒,這在高并發(fā)場景下導(dǎo)致線程頻繁地休眠和喚醒

    2024年02月01日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包