c 千萬級別高併發網路程式設計(五)

2021-09-24 20:51:29 字數 2823 閱讀 7380

部分**詳解

修正為非阻塞

vector gclients;

//全域性變數

int

process

(socket _csock)

;//不用賦值了,因為是監聽到的,不是給定的

int naddrlen =

sizeof

(sockaddr_in)

;//給定長度

socket _csock = invaid_socket;

_csock =

accept

(seradd,

(sockaddr *

)&clentaddr,naddrlen);if

(_csock = invaid_socket)

cout<<

"新客戶端加入"

push_back

(_csock);}

//time可以根據需要傳入

//修正,設定緩衝區

char szrecv[

4096]=

; dataheader *header =

null

;int nlen =

recv

(_csock,szrecv,

sizeof

(dataheader),0

);header =

(dataheader *

)szrecv;

if(nlen <=0)

switch

(header.cmd)

;int nlen =

recv

(_csock,

(char*)

&login,

sizeof

(login),0

);if(nlen <=0)

else

;//傳送也是先發包頭

send

(_csock,

(char*)

&header,

sizeof

(dataheader),0

);send

(_csock,

(char*)

&msgbuf,

sizeof

(msgbuf),0

);}else

;send

(_csock,

(char*)

&msgbuf,

sizeof

(msgbuf),0

);}}

}break

;case cmd_logout:

break

;case cmd_getinfo:

break

;default

://這裡heder的長度為0,返回乙個錯誤型別。

}}

while

(true)

int ret =

select

(_sock+1,

&fdread,

&fdwrite,

&fdexp,

null);

if(ret <0)

for(

int ii =

0; ii < gclients.

size()

;++ii)

}

fd_set其實是乙個陣列的巨集定義,實際上是一long型別的陣列,每乙個陣列元素都能與一開啟的檔案控制代碼(socket、檔案、管道、裝置等)建立聯絡,建立聯絡的工作由程式設計師完成,當呼叫select()時,由核心根據io狀態修改fd_set的內容,由此來通知執行了select()的程序哪個控制代碼可讀

fd_set

(int fd, fd_set *fdset)

;//將fd加入set集合

fd_clr

(int fd, fd_set *fdset)

;//將fd從set集合中清除

fd_isset

(int fd, fd_set *fdset)

;//檢測fd是否在set集合中,不在則返回0

fd_zero

(fd_set *fdset)

;//將set清零使集合中不含任何fd

原型:

int

select

(int nfds,

//nfds會被忽略,之所以保留是為了與早期套接字相容.linux下作用較大。所有描述符範圍,是檔案描述符最大值+1

fd_set far* readfds,

//可讀集合

fd_set far* writefds,

//可寫集合

fd_set far* exceptfds,

//異常集合

const

struct timeval far* timeout //如果再一段時間內未等到訊息,那麼就返回。

);

原先select中傳入time為null時,是阻塞模式,即一直等到有資料可操作時才返回繼續執行。否則一致阻塞在那裡。

如果是響應客戶端程式,那麼這個就可以了。

如果主動推送,那麼就需要採用非阻塞模式。

在select中傳入time

timeval t =

;//第乙個是秒,第二個是微秒

int ret =

select

(_sock+1,

&fdread,

&fdwrite,

&fdexp,t)

;

高併發網路程式設計之epoll詳解

核心 使用者空間記憶體拷貝問題,select需要複製大量的控制代碼資料結構,產生巨大的開銷 select返回的是含有整個控制代碼的陣列,應用程式需要遍歷整個陣列才能發現哪些控制代碼發生了事件 select的觸發方式是水平觸發,應用程式如果沒有完成對乙個已經就緒的檔案描述符進行io操作,那麼之後每次s...

高併發網路程式設計之epoll詳解

核心 使用者空間記憶體拷貝問題,select需要複製大量的控制代碼資料結構,產生巨大的開銷 select返回的是含有整個控制代碼的陣列,應用程式需要遍歷整個陣列才能發現哪些控制代碼發生了事件 select的觸發方式是水平觸發,應用程式如果沒有完成對乙個已經就緒的檔案描述符進行io操作,那麼之後每次s...

網路程式設計之併發網路程式設計

之前使用socket模組實現的網路程式設計都不能併發進行連線和通訊的,即乙個客戶端需要等待伺服器和另乙個客戶端通訊完成後才能和服務端進行連線和通訊。python3中提供有乙個高階內建模組socketserver來幫助我們進行併發的網路程式設計。socketserver模組處理網路請求的功能,可以通過...