2012-08-28 160 views
3

我看到了boost文檔中的官方async udp服務器示例。 還有你創建一個UDP套接字,將其綁定到本地端口和做這樣的事情:Boost asio - udp服務器

socket(ioService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)) 

socket.async_receive_from(buffer(data, max_length), senderEndpoint, boost::bind(&Request::HandleReceiveFrom, this, 
    boost::asio::placeholders::error, 
     boost::asio::placeholders::bytes_transferred)); 

我如何處理來自客戶端的多個併發UDP連接,因爲如果我嘗試創建使用

另一個插座
socket(ioService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)) 

我得到綁定錯誤,因爲我已經有一個套接字綁定到相同的端口。

編輯 我可以發送回客戶使用不同的服務器源端口的反應,但他們不會承認,即使我把響應返回給同一客戶端的IP /客戶端的目標端口的響應。

+2

也許你應該重用現有的綁定。 –

+0

@MarkGarcia創建的套接字我也需要回復給客戶端。有多個客戶端可以在同一個套接字上接收數據。 – Ghita

+0

UDP沒有任何連接。如果你想連接,你將不得不在UDP之上添加一個連接協議層,例如。爲每個對等點創建一個「連接」類,併爲每個發送消息的新發送者創建一個新實例。 –

回答

1

如果您的客戶端將其消息發送到服務器上的同一端口,則區分這些消息的唯一方法是通過遠程端口或遠程端口和遠程IP的組合。

創建從客戶端ID(例如pair<remote_ip, remote_port>)某種映射到調度器類型(例如map< pair<remote_ip, remote_port>, dispatcher>)。然後,這是由你來讓它線程化,以支持併發請求。

+0

所以,使用boost asio不一定要使用我從客戶端接收數據(即爲了將數據發回客戶端)的相同udp套接字。 – Ghita

+0

理論上所有重要的是你發送到正確的IP和正確的端口號。但是,我從來沒有試圖通過不同的套接字將數據發送回來,然後從它來的。所以我不能100%確定它會起作用。更新:實際上,客戶端會期望回覆從與發送給它的服務器端口相同的服務器端口回來。另請參閱[此答案](http://stackoverflow.com/a/763478/75889)。 – StackedCrooked

+0

我可以製作映射remote_ip,remote_port以便重放到該客戶端,但是如果我在重播時不使用相同的源端口號,客戶端將無法識別我的響應 – Ghita

4

UDP是無連接傳輸,所以就UDP而言,連接的概念是沒有意義的。

如果您想要將數據發送回消息的發起者,您需要保留async_receive_from回調中返回的sender_endpoint的副本,並將其傳回async_send_to。

這也假設客戶端也在輪詢/閱讀並期待回覆。它不需要監聽與服務器相同的綁定端口(不需要在客戶端與UDP綁定)。

我建議您閱讀Beej的網絡編程指南,以幫助您瞭解升級ASIO背後的原因。 Boost ASIO使事情變得複雜化了很多恕我直言。

http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#sendtorecv