环回中的WinSock UDP套接字创建顺序。

时间:2013-01-16 15:52:48

标签: network-programming udp winsock

我有一个专用于局域网的网络应用程序。我正在使用loopback进行测试。当我在局域网上测试时,套接字创建顺序无关紧要。如果我使用循环返回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);
}

1 个答案:

答案 0 :(得分:0)

所以我确实将实现从UDP广播更改为多播。这似乎在环回中工作,因此多个进程可以共享端口。