【问题标题】:How do i convert this blocking i/o mode into an overlapped i/o mode in c language on windows?如何在 Windows 上将这种阻塞 i/o 模式转换为 c 语言中的重叠 i/o 模式?
【发布时间】:2018-09-10 02:21:37
【问题描述】:

我正在学习在 windows 上用 c 语言进行套接字编程和多线程编程。 我设计了一个项目,其中将有三种类型的节点用于备份(服务器、客户端和存储节点)。 我创建了以下内容以拥有一台服务器和多个客户端和存储节点。 服务器需要根据请求服务的客户端类型(明确的普通客户端或存储节点)创建两种线程。 我正在使用阻塞 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:-我是初学者,请放心!

【问题讨论】:

  • '我认为原因是 winsock 不是严格线程安全的' - 我对此表示怀疑。我想现在有人会注意到的。 Occam 建议,任何错误更有可能出现在您自己的代码中..
  • 您不需要根据客户端请求创建任何线程。你真的需要使用异步 io - AcceptEx 但不是 acceptWSARecv 但不是 recv

标签: c multithreading winsock blocking overlapped-io


【解决方案1】:

您的问题不是重叠模式。是您的程序对无效数据起作用。

这样的行

_beginthreadex(0, 0, handle_client, &new_socket, 0, 0);

您正在将堆栈上的变量地址传递给新线程。该地址将在 while 循环迭代之外。并且很可能会在下次accept成功时用来存储下一个socket句柄。

要解决此问题,您可以堆分配每个套接字实例并将该函数传递给您的工作线程。

大部分重叠只会使一切复杂化。如果您不知道自己究竟为什么需要它,那么您就没有理由使用它。

【讨论】:

  • 当下次接受成功时,它肯定会被用来存储下一个套接字句柄。当两个 accept() retun 快速连续发生时会出现问题:第二个 accept() 在线程函数可以使用 'SOCKET str_node_sock = *sock_SN;' 复制出之前的值之前加载 new_socket。 '如果你不知道你为什么需要它,你就没有理由使用它' - 我同意。如果你在线程/指针上犯了这样的错误,你就会遇到重叠 I/O 和/或 IOCP 的麻烦。
猜你喜欢
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 2021-11-27
  • 1970-01-01
  • 2018-11-05
  • 1970-01-01
相关资源
最近更新 更多