2

顧客によって定義された接続プロトコルがあります。データは、UDP および TCP プロトコルを使用して 2 台の Linux コンピューター間で送信されます。IP アドレスとポートは起動時に固定されます。

私たちは 200 Hz でメッセージを送信しており、送信時間を節約するために接続を使用しています。

私の問題は、通信エラーが発生した場合、接続を切断して再初期化する必要があることです。

UDP 接続の 1 つに問題があり、必要なアドレスに再バインドされず、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 は bind の呼び出しからエラー 22 で失敗します。

ソケットを閉じる直前に、bind を明示的に呼び出して AF_UNSPEC アドレスに接続しようとしました。これでは問題は解決しません。

使用すべきオプションはありますか?

4

2 に答える 2

2

おそらくあなたは試すことができます:

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

また、2つの連続するdoConnect()呼び出しに同じソケットを渡していないことを再確認することをお勧めします(errno 22 = EINVALとして、bind()の場合、ソケットがすでにアドレスにバインドされているように見えます) )。

于 2010-09-22T17:00:57.060 に答える
0

を呼び出した後でも、下層のソケット レイヤーがポートと IP アドレスを開いたままにしている可能性がありますclose。次のいくつかを試してください。

  • と の呼び出しの間にa sleep(10)(またはそれ以上) を実行します。closedoConnect
  • をオフに設定して使用setsockoptしてソケットを構成しますSO_LINGER

これは実際には TCP 接続でより一般的に発生しますが、UDP でもこの問題が発生しない理由はわかりません。

于 2010-09-22T16:24:00.317 に答える