2010-09-22 93 views
1

我有一個由客戶定義的連接協議。數據在兩臺Linux計算機之間使用UDP和TCP協議發送。 IP地址和端口在啓動時固定。重新打開已連接的數據報套接字

我們以200赫茲發送消息,並且我一直使用連接來節省傳輸時間。

我的問題是,如果有通信錯誤,我需要拆除連接並重新初始化。

我與UDP連接的一個問題,因爲它不會重新綁定到所需要的地址,返回errno設置22

我使用的代碼是一樣的東西:

int 
doConnect(int& sock, int local_port, char *local_ip, int remote_port, char *remote_ip) 
{ 
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    struct sockaddr_in addr; 

    memset(&addr, 0, sizeof(sockaddr_in); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(local_port); 
    inet_pton(local_ip,&addr.sin_addr.s_addr); 

    if (0 > bind(sock, (struct sockaddr*)&addr, sizeof(addr))) 
    { 
     printf("Bind Error errno = %d\n", errno); 
     return ERR_BIND; 
    } 

    memset(&addr, 0, sizeof(sockaddr_in); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(remote_port); 
    inet_pton(remote_ip,&addr.sin_addr.s_addr); 

    if (0 > connect(sock, (struct sockaddr*)&addr, sizeof(addr))) 
    { 
     printf("Connect Error errno = %d\n", errno); 
     return ERR_CONNECT; 
    } 
    return ERR_OK; 
} 

方式這是用來是這樣的:

int s1(-1), s2(-1); 
doConnect(s1, 31003, "172.17.21.255", 31006, "172.17.21.1"); 
doConnect(s2, 31001, "172.17.21.3", 31004, "172.17.21.1"); 

當發生錯誤時

close(s1); 
close(s2); 

doConnect(s1, 31003, "172.17.21.255", 31006, "172.17.21.1"); 
doConnect(s2, 31001, "172.17.21.3", 31004, "172.17.21.1"); 

這裏的本地地址是172.17.21.3,我連接到172.17.21.1。 s1收聽廣播消息。

s1成功重新連接到遠程機器,但s2失敗,錯誤22從調用綁定。

我已經嘗試明確地調用綁定並在我關閉套接字之前立即連接到AF_UNSPEC地址。這並不能解決問題。

有沒有我應該使用的選項?

+0

我注意到每次調用doConnect時,在s1和s2中都會設置相同的套接字標識。 s1和s2不是相同的值。 – DanS 2010-09-23 07:54:18

回答

0

即使在您致電close後,底層套接字層可能會保留端口&的IP地址仍然打開。嘗試以下一些:

  • sleep(10)(或更多)的close和調用doConnect再次
  • 配置使用setsockoptSO_LINGER設置爲斷開

這實際上插座之間TCP連接更常見,但我認爲沒有理由UDP也不能有這個問題。

2

或許你可以嘗試:

int val = 1; 
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 

我也建議你仔細檢查你沒有通過相同插座的兩個連續doConnect()調用(如錯誤號22 = EINVAL,這in the case of bind()似乎意味着套接字已經綁定到一個地址)。

相關問題