c++ - 线程和结构通信

标签 c++ multithreading networking

我正在做一个项目,需要我接收来自许多发件人的消息。我的 recv 服务器正在使用一个线程在 UDP 协议(protocol)下连续 recv 数据。我在头文件中有一个名为 struct BufferData 的结构来组织我从客户端接收到的缓冲区。这是我的 struct 的样子:

struct BufferData
{
    char Buffer1[BYTES];
    char Buffer2[BYTES];
    char Buffer3[BYTES];
    char MixedBuffer1[BYTES];
    char MixedBuffer2[BYTES];
    char MixedBuffer3[BYTES];
};

这是我在 .cpp 文件中的 recv 线程函数。

hThread = (HANDLE)_beginthreadex(NULL, 0, &CUdpSocket::ServerRecvThread, pRecvData, 0, &threadID); // Thread caller

unsigned __stdcall CUdpSocket::ServerRecvThread(void *threadArg) 
{   
    //-----------------------------------------------
    // Initialize Winsock
    //-----------------------------------------------
    // Create a receiver socket to receive datagrams
    //-----------------------------------------------
    // Bind the socket to any address and the specified port.
    //-----------------------------------------------
    // Call the recvfrom function to receive datagrams
    // on the bound socket.

    start:
         recvfrom(RecvSocket, RecvBuf, BufLen, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
    goto start;

    //-----------------------------------------------
    // Close the socket when finished receiving datagrams
    //-----------------------------------------------
    // Clean up and exit.

    return 0;
}

但是,我不知道如何将 RecvBuf 中包含的值传递到我的 BufferData 结构中,因为这是一个线程,我不能使用直接方式。请帮忙。

谢谢。

最佳答案

当你通过调用调用_beginthreadex

_beginthreadex(NULL, 0, &CUdpSocket::ServerRecvThread, pRecvData, 0, &threadID);

该函数的第四个参数 (pRecvData) 作为 void* 参数传递给 CUdpSocket::ServerRecvThread 函数。更一般地说,如果您需要将信息传递给该函数,您可以通过将其作为最终参数传递给该函数来实现。

如果您希望能够获取接收到的数据并将其传送到 BufferData 对象中,请考虑将指向该 BufferData 对象的指针作为参数传递给线。这样,在你的接收函数中,你可以做这样的事情:

unsigned __stdcall CUdpSocket::ServerRecvThread(void *threadArg) 
{   
    /* ... setup ... */

        // Convert the argument to what it really is - a pointer to the buffer.
    BufferData* data = static_cast<BufferData*>(threadArg);

    start:
         recvfrom(RecvSocket, RecvBuf, BufLen, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize);
         /* ... code to convert the receive buffer data into a data object... */
    goto start;

    /* ... cleanup ... */
}

当然,这是非常冒险的,因为这意味着随着线程开始接收数据,它会用最新的数据覆盖缓冲区的内容。因此,我建议改为维护某种同步队列,其中包含您目前收到的所有数据包的列表。如果你这样做了,那么你的线程可以取而代之接受一个指向那个同步队列的指针,每当它接收到数据时创建它自己的 BufferData 对象,然后将它们复制到队列中。然后程序的其余部分可以通过阻塞处理它接收到的数据,直到队列中有一些数据,然后从该队列中读取数据。

此外,在完全不相关的说明中,不要使用 goto 来创建处理 recvfrom 调用的循环。请改用 while (true) 循环...它更具可读性。

希望这对您有所帮助!

关于c++ - 线程和结构通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5364605/

相关文章:

c - 替代 gethostbyname 我可以在哪里选择 DNS 服务器?

C++ cout 和 endl 无法在终端上正确打印

c++ - sqlite3_step() 有什么问题?

c 如何启动一个通过更改信号量值而停止的线程

Java 2D 游戏 : The game loop

java - 我可以在 Android 中为 DefaultHttpClient 设置 getaddrinfo 超时吗?

c++ - 为什么添加线程不能带来进一步的性能提升

c++ - 如何将文件中的数据读取到结构中?

java - Spark 如何实现任务间的内存公平?

Android:以编程方式重置电话 radio 网络信号