开发者

Threads and struct communication

I am doing a project which requires me to receive messages from many senders. My recv server is using a thread to continuously recv data under UDP protocol. I have a structure called struct BufferData in the header file to organize my received buffer from client. Here is my struct looks like:

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

And here is my recv thread function in .cpp file.

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 specifi开发者_如何学编程ed 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;
}

However, I don't know ho to pass the value contained in the RecvBuf into my BufferData structure since this a thread and I cannot use the direct way. Please help.

Thank you.


When you call _beginthreadex by calling

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

The fourth parameter to that function (pRecvData) is passed as a void* parameter into the CUdpSocket::ServerRecvThread function. More generally, if you need to communicate information into that function, you can do so by passing it as the final parameter to this function.

If you want to be able to take the data you received and communicate it into a BufferData object, consider passing a pointer to that BufferData object as a parameter to the thread. That way, inside of of your receiving function, you can do something like this:

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 ... */
}

Of course, this is very risky, because it means that as the thread starts receiving data, it will overwrite the contents of the buffer with the most recent data. Consequently, I'd suggest instead maintaining some sort of synchronized queue that contains a list of all the packets you've received so far. If you did this, then your thread could instead take in a pointer to that synchronized queue, make its own BufferData objects whenever it receives data, and then copy them into the queue. The rest of your program could then process the data it receives by blocking until the queue has some data in it, then reading the data out of that queue.

Also, on a totally unrelated note, don't use goto to make a loop that processes the recvfrom calls. Use a while (true) loop instead... it's more readable.

Hope this helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜