HI
 
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.
 
 
Yes, that was the same idea.
 
The client just creates a socket and Connects to a known IP - Port No and sends data.  One you call connect I think Window assigns a port no to the socket so you can just call recv??? 
 
 
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. 
 
Hmm I not sure that is right.  I think we may be talking about two different things here.  I'm talking about making a connection on a connectionless socket (confused yet?)  Reading page 207 of the "Network programming for Microsoft Windows"... states...
 
//------------------------
 
Another method of receiving  (and sending) data on a connectionless socket is to establish a connection.  This might sound strange, but it's not quite what it sound like.  Once a connectionless socket is created, you can call connect or WSAConnect with the SOCKADDR parameter to set the address of the remote machine to communicate with.  No actual connection is made, however.  The socket address passed into a connection function is associated with the socket so that recv and WSARecv can be used instead of recvfrom or WSARecvfrom because the data's origin is known.  The ability to connect a datagram socket is handy if you intend to communicate with only one endpoint at a time in your application.
 
//-------------------------
 
 
 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.
 
 
So you think I have to call the bind call on the client as well as the server and specify the port I think it should use??  This may well be correct.  When I bind the client side to a port no the program works, its just coincidence that it is the same port no as the server.
 
When I tried to use the Connect (from above) ( with no bind ) Windows assigned the port no to the socket on the client, I know this as each time I tried to connect to the server (restart the client app) the port no that the client used increased by one.  The only problem I had with this is that I could only see traffic travelling in one direction. 
 
Now I read something about things getting bound to the wrong IP if you do certain things - or if you do them in a certain order..  I can't really remember ( will have to look it up ) but I think I may have to bind the client to port 0 to let Windows assign the port?  Then call connect to connect the client to the server??
 
 
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.
 
That's pretty much what happens.  Instead of having a lockable queue I have an event set-up and after the first recv it signals the event so that it can send the data.
 
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.
 
 
True, however the amount of slowdown doesn't seem to have any serious problems for what I am doing.  Although for another project I will be working on I defiantly will use IOCP and UDP.
 
 
If your code works like what I have above, then we are right, this is how the udp stuff works.
 
Yeah, pretty much - just the odd niggle that's been bugging me - such as the bind thing.....
 
Regards
Max
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.300 / Virus Database: 266.3.0 - Release Date: Mon 21/02/2005
_______________________________________________
msvc mailing list
[email protected]
See http://beginthread.com/mailman/listinfo/msvc_beginthread.com for 
subscription changes, and list archive.

Reply via email to