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!
精彩评论