如果已由其他应用程序打开,则无法在Windows XP上打开SSDP套接字

时间:2011-06-14 13:09:28

标签: windows sockets udp multicast

我想在端口1900上侦听SSDP多播。该端口已由Windows Discovery Service打开。尽管使用了SO_REUSEADDR套接字选项,但我无法绑定套接字。我以管理员身份启动了我的应用程序。

如果我停止服务,启动我的应用程序,然后重新启动服务,然后两者都获取消息。我做错了什么?

static SOCKET CreateSocket(const char *ccAddress, unsigned short ulPort, struct IfPoolItem *item) {
struct sockaddr_in sAddr;
struct ip_mreq mc_req;
SOCKET sRet;
char cSockParam = TRUE;

/* create a socket */
if((sRet = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
    return(INVALID_SOCKET);
}

item->s = sRet;

if (setsockopt(sRet, IPPROTO_IP, SO_REUSEADDR, &cSockParam, sizeof(cSockParam)) == -1) {
    int iTmp = WSAGetLastError();
    return (INVALID_SOCKET);
}

/* bind the socket to the given port */
memset(&sAddr, 0, sizeof(sAddr));
sAddr.sin_family = AF_INET;
sAddr.sin_addr.s_addr = inet_addr(item->szIP);
sAddr.sin_port = htons(ulPort);
if(bind(sRet, (struct sockaddr *)&sAddr, sizeof(sAddr)) == SOCKET_ERROR)
{
    int iTmp = WSAGetLastError();
    closesocket(sRet);
    return(INVALID_SOCKET);
}

cSockParam = 4;
if (setsockopt(sRet, IPPROTO_IP, IP_MULTICAST_TTL, &cSockParam, sizeof(cSockParam)) == -1) {
    int iTmp = WSAGetLastError();
    return (INVALID_SOCKET);
}

/* Construct an IGMP join request structure */
mc_req.imr_multiaddr.s_addr = inet_addr(ccAddress);
mc_req.imr_interface.s_addr = inet_addr(item->szIP);

/* Send an ADD_MEMBERSHIP message via setsockopt */
if((setsockopt(sRet, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *) &mc_req, sizeof(mc_req))) == -1) {
    int iTmp = WSAGetLastError();
    return (INVALID_SOCKET);
}

/* Return the created socket. */
return(sRet);

}

2 个答案:

答案 0 :(得分:1)

我不是套接字专家,但是如果你看一下msdn page,它就说SO_REUSEADDR应该与level = SOL_SOCKET参数一起使用。所以你打电话可能应该是

setsockopt(sRet, SOL_SOCKET, SO_REUSEADDR,&cSockParam, sizeof(cSockParam))

请尝试这个,让我知道它是否有任何区别

答案 1 :(得分:0)

我不确定这是否是您的问题,但WDS可能正在使用阻止您的bind()的SO_EXCLUSIVEADDRUSE。此链接中的文档似乎描述了您要报告的行为。