**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)||(
{
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
實在沒有積分,可留下郵箱,有時間再轉發