1. 程式人生 > >socket程式設計總結(埠使用/bind/select/iocp等)----windows環境下

socket程式設計總結(埠使用/bind/select/iocp等)----windows環境下

1、理論上一臺伺服器最多能接受多少個連線?是65535嗎?

           理論上要大於65535,若計算機配置及頻寬等條件無限,可以實現無限連線:

背景A監聽埠和通訊埠是同一個:socket程式設計時服務端會指定一個埠進行監聽,客戶端連線進來後返回一個新的socket,這個socket是客戶端連線

                       進來的socket,用來區別不同的客戶端,因此不管有多少客戶端連線進來,若一開始程式就只使用了一個監聽埠,則不會佔用其它新的埠

                B、通常所說的65535限制是針對客戶端而言。一臺電腦開啟n個客戶端與伺服器連線,則客戶端消耗n個埠,而n<=65535

      1)、雖然windows預設有65535個埠(XP,其它系統不知),但是可以通過更改系統配置檔案開啟更多埠

      2)、從socket程式設計可知,連線進來的客戶端是ip+port形式確定的,一個ip在預設情況下最多有65535個埠,而ip不定,所以結果肯定大於65535

      3)、雖然理論上可以支援超過65536的連線,但實際中要實現這樣的伺服器,並且還要求是長連線的話,不管是對伺服器配置,伺服器頻寬,還是對程式設計師都是一個考驗

2、使用bind與不使用bind的區別

     1)、當使用TCP協議時,服務端必須使用bind,這樣才能實時監聽隨時有可能連線進來的客戶端,而客戶端則沒必要使用bind(這時,客戶端隨機分配)

     2)、當使用UDP協議時,若是C/S模式,則服務端客戶端有無bind都沒太大影響,如果是對等通訊(P2P等)則兩端都需要bind

3、iocp

      A、使用CreateIoCompletionPort、GetQueuedCompletionStatus、recv/recvFrom、send/sendTo組成的完成埠

      B、使用CreateIoCompletionPort、GetQueuedCompletionStatus、WSARecv/WSARecvFrom、send/sendTo組成的完成埠

      C、使用CreateIoCompletionPort、GetQueuedCompletionStatus、WSARecv/WSARecvFrom、WSASend(單發)組成的完成埠

      D、使用CreateIoCompletionPort、GetQueuedCompletionStatus、WSARecv/WSARecvFrom、WSASend(群發)、PostQueuedCompletionStatus組成的完成埠

      1)、使用WSASend傳送訊息時(已註釋):

int

WSAAPI

WSASend(

    __in SOCKET s,

    __in_ecount(dwBufferCount) LPWSABUF lpBuffers,                  //可使用臨時變數,而WSARecv的此引數不能,只能使用全域性變數

    __in DWORD dwBufferCount,

    __out_opt LPDWORD lpNumberOfBytesSent,

    __in DWORD dwFlags,

    __inout_opt LPWSAOVERLAPPED lpOverlapped,                      //只能使用全域性變數?!WSARecv一樣?!(暫未測試)

    __in_opt LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

    );

使用WSASend還需要注意一點的是每WSASend一次lpOverlapped引數都要重新再堆分配,這樣可以避免一個WSASend還沒完成,下一個WSASend破壞了Overlapped,最終導致資料傳送出現問題。當然如果你能百分百保證每次WSASend時前一次使用的Overlapped已經結束,則可以只使用一個Overlapped結構

或者1個SOCKET對應一個

2)、WSARecv接收時

     a、當WSABUF的len變數賦值為buffer長度時,GetQueuedCompletionStatus相應後,可直接依據CONTAINING_RECORD巨集獲取到接收到的資料,即                       WSABUF.buf裡的資料

     b、當WSABUF的len變數賦值為0時,GetQueuedCompletionStatus相應後,WSABUF.buf還是為空?!還需要用recv函式接收資料?!用於接收的buffer

           為WSABUF.buf指向的buffer