2011-12-15 8 views
1

UDP(WinSocks/C++)でシンプルなサーバとクライアントを使用しています。sendtoで送信するときにUDPでクライアントを強制的にオープンする方法

私はsendto経由でデータグラムのクライアント - >サーバを送り、recvfrom機能から得られたipと​​ポートを使ってサーバからクライアントに応答します。

私がいることが分かった:サーバーのWindowsから返信しようとすると、WSAECONNRESET(ポートが閉じていることを意味 - http://support.microsoft.com/kb/263823)を返した場合、クライアントからのすべてのsendtoが

  • 別のポートから送信されている

    サーバからクライアントに正しく応答するにはどうすればいいですか?(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

    +0

    どのポートにバインドする必要がありますか? – PiotrK

    +0

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms740148%28v=vs.85%29.aspx < - "注:ソケットがオープンされている場合、setsockopt呼び出しが行われ、 sendto呼び出しが行われると、Windows Socketsは暗黙のバインド関数呼び出しを実行します。そして、これは: http://cboard.cprogramming.com/networking-device-communication/71964-udp-client-needs-bind.html – PiotrK

    答えて

    4

    送信するローカルポートを指定するには、 "bind"関数を呼び出します。以下のポート4567の使用例bind.Callからの戻り値を確認してください。ソケットを作成した後でこのコードを呼び出してください。

    sockaddr_in local = {}; 
    local.family = AF_INET; 
    local.port = htons(4567); 
    local.addr = INADDR_ANY; 
    
    bind(internal->sock,(sockaddr*)&local, sizeof(local)); 
    

    あなたはポートゼロの代わりに4567に結合した場合、OSはあなたのためのランダムなポートを選択し、すべての後続の送信のためにそれを使用して受信します。 getsocknameを呼び出して、bindを呼び出した後にどのポートがあなたのために選択したかを知ることができます。

    +0

    4567ではなくポート0にビンすると、osはあなたのためにランダムなポートを選び、後続のすべての送受信に使用します。 getsocknameを呼び出して、bindを呼び出した後にどのポートがあなたのために選択したかを知ることができます。 – selbie

    +0

    ハハ、とてもシンプルです:私はrecvfrom後にソースポートをntohsしませんでした。あなたのポートビーイングを明示する提案は、私に手がかりを与えました – PiotrK

    関連する問題