我有一个使用套接字的应用程序(我没有写,所以请耐心等待)当我尝试关闭套接字时,closesocket()失败并出现错误WSAEOPNOTSUPP并且套接字粘在...如,它没有被完全删除。
套接字创建如下:
bool Socket::CreateConnection()
{
int error;
struct addrinfo hints;
struct addrinfo *list = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
error = getaddrinfo(socketAddress.c_str(), socketPort.c_str(), &hints, &list);
if (error)
{
Log().RecordError("Unable to initialize connection to server", WSAGetLastError(), EventTypeError);
}
for (struct addrinfo *ptr = list; ptr != NULL; ptr = ptr->ai_next)
{
connection = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (connection == INVALID_SOCKET)
{
Log().RecordError("Unable to initialize socket connection", WSAGetLastError(), EventTypeError);
break;
}
error = connect(connection, ptr->ai_addr, (int)ptr->ai_addrlen);
if (error == SOCKET_ERROR)
{
closesocket(connection);
connection = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(list);
return connection != INVALID_SOCKET;
}
该类的析构函数:
Socket::~Socket()
{
int error;
if (connection != INVALID_SOCKET)
{
continueReading = false;
error = shutdown(connection, SD_SEND);
if (error != SOCKET_ERROR)
{
/* Finish any necessary receives to politely close the socket */
int length;
do
{
char buffer[1024];
length = recv(connection, buffer, sizeof(buffer)/sizeof(*buffer), MSG_WAITALL);
} while (length > 0);
}
else
{
Log().RecordError("Error shutting down connection to server", WSAGetLastError(), EventTypeError);
}
closesocket(connection); //Fails HERE
int wsa_err = WSAGetLastError();
if(wsa_err)
Log().RecordError("closesocket() error", wsa_err, EventTypeError);
}
if (winsockInitialized)
{
WSACleanup();
}
}
任何人都知道为什么会发生这种情况?
答案 0 :(得分:2)
你没有检查closesocket()上的返回码,这意味着WSAGetLastError()可能与closesocket操作有关,也可能没有。
答案 1 :(得分:0)
我不是Windows套件大师,但我还是会尝试一下..
您确定WSAGetLastError()
返回的代码涉及对closesocket()
的调用吗?
引用msdn:
...这是必要的,因为某些功能可能将上一个扩展错误代码重置为0,如果它们成功...
我假设你可能有一个先前的套接字相关调用失败(?)。 Msdn告诉每个套接字相关的调用后,你必须通过调用WSASetLastError()
来阻止它。
要专门重置扩展错误代码,请使用WSASetLastError函数调用,并将iError参数设置为零。
答案 2 :(得分:0)
错误状态几乎肯定会从之前的操作中遗留下来。 Winsock函数在成功时通常不会清除错误状态。
检查closesocket()的返回码。如果这不表示错误,那么WSAGetLastError()的值是没有意义的。
答案 3 :(得分:0)
错误代码由recv遗留,因为Windows xp不支持标志MSG_WAITALL