我正在学习在Windows上进行套接字编程和多线程编程。 我设计了一个项目,其中有三种类型的节点用于备份(服务器,客户端和存储节点)。 我创建了以下内容以拥有一个服务器以及多个客户端和存储节点。 服务器需要根据请求服务的客户端类型(显式正常客户端或存储节点)创建两种线程。 我正在使用阻止i / o模式。 代码的结构如下:
服务器:
int main()
{
//initialization and other things
while ((new_socket = accept(srv_sock, (struct sockaddr *)&client, &c)) != INVALID_SOCKET)
{
_beginthreadex(0, 0, handle_client, &new_socket, 0, 0);
}
}
uint32_t __stdcall handle_client(void *data)
{
SOCKET* sock = (SOCKET*)data;
SOCKET client_sock = *sock;
//other
recv_size = recv(client_sock, header_buf, HDR_LEN, 0);
//fixed length header
if (!strncmp(connect_with, "storageNode", strlen(connect_with)))
//check if client is a normal client or a storage node
{
_beginthreadex(0, 0, handle_storage_node, sock, 0, 0);
return 0;
}
else
{
//continue with request from normal client
}
}
uint32_t __stdcall handle_storage_node(void *data)
{
SOCKET* sock_SN = (SOCKET*)data;
SOCKET str_node_sock = *sock_SN;
//continue with request from storage node
}
我希望将其更改为重叠i / o的其他主要原因是因为有些时候(可能是一千次)来自普通客户端的消息最终会作为来自存储节点和消息的消息反之亦然。 我认为其原因是winsock并非严格的线程安全。另外作为初学者,我想学习以另一种方式做到这一点。 那么,重叠i / o实现的等效结构应该是什么?如何阻止消息传递到错误的线程?
PS: - 我是初学者,对我很轻松!
答案 0 :(得分:1)
您的问题不是重叠模式。这是因为你的程序对无效数据起作用。
在这样的行中
_beginthreadex(0, 0, handle_client, &new_socket, 0, 0);
您正在将堆栈上变量的地址传递给新线程。该地址将在while循环迭代之外。当下一次接受成功时,很可能会用来存储下一个套接字句柄。
要修复此问题,您可以堆分配每个套接字实例并将该函数传递给工作线程。
重叠最多只会让一切变得复杂。如果您不知道为什么需要它,您就没有理由使用它。