1

我有一个用于专用 LAN 的网络应用程序。我正在使用环回进行测试。当我在 LAN 上测试时,套接字创建顺序无关紧要。如果我使用环回 127.0.0.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 回答