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