我现在正在调试我的套接字应用程序,包括运行和持续关闭它。我的问题是当我运行并关闭它然后再次运行它我收到10048错误代码,指示已经在使用的地址。我尝试将套接字描述符设置为SO_REUSEADDR
,但如果我一直运行并关闭我的应用程序,仍然会收到10048错误代码。
int getExternalpAddress(char *upnpDeviceIp, char *localIp, char *externalIpAddress) {
WSADATA wsaData;
struct sockaddr_in upnpControl,
upnpDevice;
int i = 0,
j = 0,
result = -1,
bodyLen = 0;
char c,
*tmp = NULL,
*pLen = NULL,
*bodyResponse = NULL,
pBodyLen[5],
responseHeader[512],
getExternalIpRequest[622];
int reuseAddress = 1;
ZeroMemory(getExternalIpRequest, 622);
StringCbPrintf(getExternalIpRequest, 622,
"POST /UD/?3 HTTP/1.1\r\n"
"Content-Type: text/xml; charset=\"utf-8\"\r\n"
"SOAPAction: \"urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress\"\r\n"
"User-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows 9x)\r\n"
"Host: %s\r\n"
"Content-Length: 303\r\n"
"Connection: Close\r\n"
"Cache-Control: no-cache\r\n"
"Pragma: no-cache\r\n\r\n"
"<?xml version=\"1.0\"?>"
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
"<SOAP-ENV:Body>"
"<m:GetExternalIPAddress xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\"/>"
"</SOAP-ENV:Body>"
"</SOAP-ENV:Envelope>\r\n\r\n", upnpDeviceIp);
result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if(result != 0)
return WSAGetLastError();
SOCKET sock = INVALID_SOCKET;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == SOCKET_ERROR)
return WSAGetLastError();
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseAddress, sizeof(reuseAddress)))
return WSAGetLastError();
ZeroMemory(&upnpControl, sizeof(upnpControl));
upnpControl.sin_family = AF_INET;
if(localIp == NULL)
upnpControl.sin_addr.s_addr = INADDR_ANY;
else
upnpControl.sin_addr.s_addr = inet_addr(localIp);
upnpControl.sin_port = htons(8000);
if(bind(sock, (struct sockaddr *)&upnpControl, sizeof(struct sockaddr)) == SOCKET_ERROR)
return WSAGetLastError();
ZeroMemory(&upnpDevice, sizeof(upnpDevice));
upnpDevice.sin_family = AF_INET;
upnpDevice.sin_port = htons(80);
upnpDevice.sin_addr.s_addr = inet_addr(upnpDeviceIp);
if(connect(sock, (struct sockaddr *)&upnpDevice, sizeof(struct sockaddr)) == SOCKET_ERROR)
return WSAGetLastError();
result = send(sock, getExternalIpRequest, lstrlen(getExternalIpRequest), 0);
if(result != lstrlen(getExternalIpRequest))
return WSAGetLastError();
ZeroMemory(responseHeader, 512);
while(recv(sock, &c, 1, 0) > 0) {
responseHeader[i] = c;
if(strstr(responseHeader, "\r\n\r\n")) {
// Move the pointer to the first digit
pLen = strstr(responseHeader, "Content-Length: ") + 16;
ZeroMemory(pBodyLen, 5);
// Get the body length
while(*pLen != '\r') {
pBodyLen[j] = *pLen;
*pLen++;
++j;
}
bodyLen = atoi(pBodyLen);
j = 0;
bodyResponse = (char *)MALLOC(bodyLen);
while(recv(sock, &c, 1, 0) > 0) {
bodyResponse[j] = c;
++j;
if(j == bodyLen) { // We got the HTTP body
closesocket(sock);
}
}
}
++i;
}
i = 0;
tmp = strstr(bodyResponse, "<NewExternalIPAddress>") + 22;
ZeroMemory(externalIpAddress, 16);
while(*tmp != '<') {
externalIpAddress[i] = *tmp;
*tmp++;
++i;
}
FREE(bodyResponse);
WSACleanup();
return 0;
}