1

プライベート LAN 用のネットワーク アプリケーションがあります。ループバックを使用してテストを行っています。LAN でテストする場合、ソケットの作成順序は重要ではありません。ループバック 127.0.0.1 を使用してテストすると、ソケットの作成順序に問題があります。ループバックで異なるのはなぜですか?

詳細はこちら...

1 つのサーバーと多数のクライアント インスタンスがあります。サーバーは UDP 経由でデータをブロードキャストしています。クライアントはデータを受け取り、処理します。

サーバーまたはクライアントの開始順序をネットワーク層が気にしないようにする必要があります。私の場合、プロセス作成を管理するのは難しいです。アプリケーション インスタンスは、任意の順序でネットワーク上で開始でき、データが送信されたときに UDP ポートでブロードキャストされたデータを確認できる必要があります。

しかし、UDP ソケットをセットアップする方法に、順序付けを強制する何かがあります。クライアントを起動してから、サーバーを起動する必要があります。サーバーが UDP ブロードキャストを実行した後にクライアントを起動すると、クライアント ソケットがデータを受信しません。実行中のサーバー インスタンスを強制的に破棄して UDP ソケットを再構築すると、突然すべてのクライアントがデータの受信を開始します。

ソケットの作成方法に問題があるに違いありません。クライアントとサーバーのコードは、共有関数ライブラリを使用して UDP ソケットを作成します。したがって、サーバーは m_fdOut で送信しています。クライアントの各インスタンスは m_fdIn で受信しています。

ここで何が間違っていますか?

SOCKET m_fdIn;
SOCKET m_fdOut;

if ((m_fdIn = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
    WARNF("socket failed, winsock error %d\n", WSAGetLastError());
    exit(1);
}

if ((m_fdOut = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
    WARNF("socket failed, winsock error %d\n", WSAGetLastError());
    exit(1);
}


int sockopt = 1;
if (setsockopt(m_fdOut, SOL_SOCKET, SO_BROADCAST, (char *)&sockopt,
     sizeof(sockopt)) < 0)
{
    WARNF("setsockopt failed, winsock error %d\n", WSAGetLastError());
    exit(1);
}

sockopt = readPreference<int>("SOL_RCVBUF", 512*1024);
if (setsockopt(m_fdIn, SOL_SOCKET, SO_RCVBUF, (char *)&sockopt, sizeof(sockopt)) < 0)
{
    WARNF("setsockopt failed, winsock error %d\n", WSAGetLastError());
    exit(1);
}

sockopt = 1;
if (setsockopt(m_fdIn, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)) < 0)
{
    WARNF("setsockopt failed, winsock error %d\n", WSAGetLastError());
    exit(1);
}

sockopt = readPreference<int>("IP_MULTICAST_TTL", 32);
if (setsockopt(m_fdOut, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&sockopt, sizeof(sockopt)) < 0)
{
    WARNF("setsockopt failed, winsock error %d\n", WSAGetLastError());
    exit(1);
}

String destAdd = "255.255.255.255"
int portNumber = 1234;
int n1, n2, n3 ,n4;
if (sscanf(destAddr, "%d.%d.%d.%d", &n1, &n2, &n3, &n4) != 4)
{
    n1 = n2 = n3 = n4 = 255;
}

u_long bcastAddr = (n1<<24) | (n2<<16) | (n3<<8) | n4;
outAddr.sin_family = AF_INET;
outAddr.sin_port = htons(portNumber);
outAddr.sin_addr.s_addr = htonl(bcastAddr);

struct sockaddr_in in_name;
in_name.sin_family = AF_INET;
in_name.sin_addr.s_addr = INADDR_ANY;
in_name.sin_port = htons(portNumber);

if (bind(m_fdIn, (struct sockaddr *)&in_name, sizeof(in_name)) < 0)
{
    WARNF("bind failed, winsock error %d\n", WSAGetLastError());
    exit(1);
}
4

1 に答える 1

0

そこで、実装を UDP ブロードキャストからマルチキャストに変更しました。複数のプロセスがポートを共有できるように、ループバックで機能するようです。

于 2013-01-23T15:49:14.550 に答える