我想退出阻止recv()
来电。基于此question,我应该执行以下操作:
shutdown(s, SD_RECEIVE);
但它不起作用,recv()
仍在阻止!
修改
这是我使用的代码:
#include <stdio.h>
#include <WinSock2.h>
#include <Windows.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
unsigned int __stdcall recvThread(void *p)
{
SOCKET s = *((SOCKET*)p);
char buffer[2048];
int size;
do
{
size = recv(s, buffer, 2048, 0);
if (size > 0)
{
printf("Some data received\n");
}
else if (size == 0)
{
printf("Disconnected\n");
}
else
{
printf("Disconnected, error occured\n");
}
} while (size > 0);
return 0;
}
int main()
{
// Initialize Winsock
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
// Create socket
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
// Connect
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("192.168.1.4");
addr.sin_port = htons(atoi("12345"));
if (connect(s, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
printf("Unable to connect\n");
}
else
{
printf("Connected\n");
}
// Start recv() thread
HANDLE hRecvThread = (HANDLE)_beginthreadex(0, 0, recvThread, &s, 0, 0);
Sleep(3000);
// Exit blocking recv()
shutdown(s, SD_RECEIVE);
getchar();
return 0;
}
答案 0 :(得分:1)
您需要按照链接到的问题中提到的方式关闭输入。
请参阅msdn上的shutdown()文档以及此处:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms738547%28v=vs.85%29.aspx
文件中的相关引用:
关闭功能用于所有类型的插座,以禁用接收,传输或两者兼而有之 如果how参数是SD_RECEIVE,则不允许对套接字上的recv函数进行后续调用。这对较低协议层没有影响。对于TCP套接字,如果仍有等待接收的套接字上排队的数据,或者数据随后到达,则重置连接,因为无法将数据传递给用户。对于UDP套接字,接受传入的数据报并排队。在任何情况下都不会生成ICMP错误包 如果how参数是SD_SEND,则不允许后续调用send函数。对于TCP套接字,在接收方发送并确认所有数据后,将发送FIN 如上所述,设置SD_BOTH如何禁用发送和接收。
关键是发送FIN。这将由服务器处理,它将关闭套接字,导致你的recv()调用返回。