I think this would more correctly look like this
rough idea:
SOCKET sock = INVALID_SOCKET;
char buf[
SOME_BIG_NUMBER_BIG_ENOUGH_TO_HOLD_DATA_SENT ];
char FromAddr[ 1024 ]; // plenty
big
int nFromAddrSize = 0;
int nRtn = 0;
int nResponseLen = 0;
sock = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_IP
);
if( sock == INVALID_SOCKET )
{
// oops
return;
}
::bind( sock, /* insert local address/port here
*/ );
nRtn = ::recvfrom( s, buf, sizeof( buf ), 0,
&FromAddr, &nFromAddrSize );
while( nRtn && nRtn != SOCKET_ERROR
)
{
nResponseLen = ProcessData(
buf, nRtn );
::sendto( s, buf /* which now
hold the response */, nResponseLen, 0, &FromAddr, nFromAddrSize
);
nRtn
= ::recvfrom( s, buf, sizeof( buf ), 0, &FromAddr, &nFromAddrSize
);
}
Notice we are using the address given to us in
the recv to send the data back to. I think this was the same idea you had,
but I couldn't quite see it in the code you posted.
First, you're getting the terminology
wrong. In udp there is no "connection" so the client can't create a socket
and connect to anything. It creates a socket and sends data to the server
addr/port. Look at the ::bind( ) Remarks in help. You'll note that
only for tcp if the port is specified as 0 that windows will assign the port
number. You see, in udp this just isn't necessary. In tcp you can
only have one app receiving and sending data on a particular port. But
with udp you can have several apps all receiving data on the same port, and yes
it's a pain to be avoided but is possible (at least you can do it in
UNIX). So I think for the bind call in udp you have to specify the port
even for the client.
Your client code will look roughly like what I
posted above for the server except it will do a ::sendto( ) first then a
::recvfrom( ), and it may not loop on the wile( ) if it is supposed to make a
querry and then exit.
I do like your multithreaded approach for the
server (but not necesarily needed for the client, but your specific needs may
require it). The server would ::recvfrom( ) and throw the result into a
shared/lockable queue and trigger an event. The "worker thread" would then
pull the data from the queue, process it and then either put the result on
another queue for a "sending thread", or go ahead and send it
itself.
And then you're just one step away from IOCP, you
just have a handfull of threads that both receive, do the work, and send the
results. That way there are no context switches between receiving,
working, and sending, unless the timeslice expires and you can't help
that. In the scenario above you have manditory context switches between
the recvfrom, worker, and sending threads. And context switches will slow
the entire system down.
I agree.
If your code works like what I have above, then
we are right, this is how the udp stuff works.
/dev
|
_______________________________________________ msvc mailing list [email protected] See http://beginthread.com/mailman/listinfo/msvc_beginthread.com for subscription changes, and list archive.
