1. 程式人生 > >**epoll實現tcp百萬級高併發測試**

**epoll實現tcp百萬級高併發測試**

						**epoll實現高併發測試**

1,準備環境
Server 端:

系統埠限制 預設檢視:cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999(在/etc/sysctl.conf修改)

最大檔案控制代碼限制:檢視:cat /proc/sys/fs/file-nr
297440 0 297373(最大值系統計算)
備註:這裡最大值與記憶體相關,在把虛擬機器的記憶體由2G變成3G後由17W變成19W,最後修改fs.file-max後提升比較大
這裡原始值為17W左右,修改/etc/sysctl.conf裡定義fs.file-max = 1000000 來調整大小,後續有需要繼續修改除錯

檢視系統網路引數相關配置:Vim /etc/sysctl.conf

檢視其它限制配置:vim /etc/security/limits.conf

執行 ulimit -n 輸出1024,說明對於一個程序而言最多隻能開啟1024個檔案,所以你要採用此預設配置最多也就可以併發上千個TCP連線。
臨時修改:ulimit -n 1048576,但是這種臨時修改只對當前登入的使用者目前使用的環境有效,系統重啟或使用者退出會就失效。

需要使用到的命令:
ulimit -SHn 1048576
sysctl -w net.ipv4.ip_local_port_range=“1024 65535”

Client配置:

客戶端需要的命令

埠限制:如服務端進行修改
檔案埠限制:如服務端,或在命令列做以下配置

echo 2000000 >/proc/sys/fs/nr_open
ulimit –SHn 1048576
sysctl -w net.ipv4.ip_local_port_range=“1024 65535”

程式碼實現流程:
Server :

Listenfd = socket(AF_INET,);
setNonBlocking();
Setsockopt(listenfd, ,SO_REUSEADDR,);//除錯時提高效率,回收速度太慢
Bind(listenfd);
Epollfd = Epoll_create();
En. events=EPOLLIN;//服務端只讀,在收到客戶端資訊後,修改事件,再寫資料
epoll_ctl(Epollfd, EPOLL_CTL_ADD, listenfd, ev);
while(1)
{
nEventNum = Epoll_wait(eopllfd,ev,)
for(I = 0; I < nEventNum ; i++)//對事件進行輪詢
{
If((.event == EPOLLERR)||(

.event == EPOLLHUP))
{
Close;
Continue;
}
Else if(event.data.fd == listenfd)
{

}

If(.event == EPOLLIN)
{
Ret = recv(fd,);
Printf();
ev.events = EPOLLOUT;
epoll_ctl();
}
Else if(
.event == EPOLLOUT)
{
Send();
ev.events = EPOLLIN;
epoll_ctl();

}

}
}
服務端的連線及列印情況如下:

在這裡插入圖片描述
建立到62W時

在這裡插入圖片描述
此錯誤一般是磁碟滿導致,但是在這裡是客戶端在進行epoll_ctl時,記憶體已滿導致註冊epoll事件失敗,理論上服務端10m個併發長連線應該可以實現。

原因是因為我在伺服器端裝了二個ubuntu的虛擬機器,記憶體受到了很大限制,部分引數沒有配置最大,因此百萬級連線無論是從理論還是從實際測試效果來看,都是可行的

Client :

Epollfd = epoll_creat(EVENT);

For(;i<CLIENMAX;)
{
Clisockfd = socket();
Bind(ser_addr)
Bind(cli_addr);//為了實現客戶端上多IP對服務端進行連線,這裡需要繫結客戶端的IP 埠為0,則是由系統隨機分配。
Connect();
ev.data.fd= Clisockfd;
ev.events=EPOLLIN|EPOLLET;
epoll_ctl (Epollfd ,EPOLL_CTL_ADD,clisockfd,&en);
}

While(1)
{
Scanf();//做了一個小的輸入sockfd與服務端進行通訊
ev.data.fd= writefd;
ev.events=EPOLLOUT|EPOLLET;
if (epoll_ctl(nEpollfd,EPOLL_CTL_MOD,writefd,&ev) < 0)

eventNum= Epoll_wait(Epollfd,);
for(;i< eventNum;)//輪詢事件

{
If(*.event == ERR|HUP)
{
Close(fd);
Continue;
}
If(events[i].events & EPOLLOUT)
{
Send();
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(nEpollfd, EPOLL_CTL_MOD, nSockfd, &ev);
}
Else if(events[i].events & EPOLLIN)
{
Recv()
}
}

}

測試中還有加入在服務端通過多程序,繫結多個IP來與客戶端進行建立連線,這個數量級又是一個成倍的增加,但是由於我們這裡需要測試的是單程序的多併發最大連線數測試

原始碼下載如下:https://download.csdn.net/download/u014220105/10831946

實在沒有積分,可留下郵箱,有時間再轉發