线程和结构通信

时间:2011-03-19 20:10:49

标签: c++ multithreading networking

我正在做一个项目,要求我接收来自许多发件人的邮件。我的recv服务器使用一个线程在UDP协议下连续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结构,因为这个线程和我不能直接使用。请帮忙。

谢谢。

1 个答案:

答案 0 :(得分:5)

通过致电

致电_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)循环代替...它更具可读性。

希望这有帮助!