2011-12-15 91 views
1

我在UDP(WinSocks/C++)中有簡單的服務器和客戶端。如何在用sendto發送時強制UDP客戶端打開端口

我通過sendto發送數據報客戶端 - >服務器,並使用從recvfrom函數獲得的IP和端口從服務器回覆到客戶端。

我發現:

  1. 每SENDTO從客戶正在從不同的端口發送
  2. 當試圖從服務器的Windows回覆返回WSAECONNRESET(這意味着端口是關閉 - http://support.microsoft.com/kb/263823

如何從服務器正確回答客戶端(即使用sendto發送時強制客戶端綁定在客戶端上?)

編輯:添加一些源代碼:

bool InitClient() 
{ 
    internal->sock = socket(PF_INET, SOCK_DGRAM, 0); 
    char8 yes = 1; 
    setsockopt(internal->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32)); 
    return internal->sock != -1; 
} 
void Send(const IpAddress & target, const uint16 port, const char8 * data, int32 size) 
{ 
    sockaddr_in trgt; 
    memset(&trgt, 0, sizeof(trgt)); 
    trgt.sin_family = AF_INET; 
    trgt.sin_port = htons(port); 
    trgt.sin_addr.s_addr = target.GetRaw(); 

    if(sendto(internal->sock, (const char8 *)data, size, 0, (PSOCKADDR)&trgt, sizeof(trgt)) == SOCKET_ERROR) 
    { 
     LOG("Network sending error: %d", WSAGetLastError()); 
    } 
} 
+0

看看[這個答案](http://stackoverflow.com/a/4487043/377270)可以幫助你嗎?我應該綁定哪個端口的 – sarnold 2011-12-15 22:25:20

+0

? – PiotrK 2011-12-15 22:30:21

回答

4

調用「綁定」功能來指定本地端口發送。下面使用端口4567的示例。確保檢查bind的返回值。創建套接字後調用此代碼。

sockaddr_in local = {}; 
local.family = AF_INET; 
local.port = htons(4567); 
local.addr = INADDR_ANY; 

bind(internal->sock,(sockaddr*)&local, sizeof(local)); 

如果綁定端口零,而不是4567,則操作系統將選擇一個隨機端口,爲您和使用它的所有後續的發送和接收。你可以調用getsockname來發現調用綁定之後os爲你選擇的端口。