UDP / Sockets Design Question
Hi,
Before starting with my code I was wondering whether I could get some advice on the best way to implement the following.
Essentially I have a small PCA that I can communicate to over a socket connection using UDP. I would like to be able to send the board commands but simultaneously be receiving data that the board is sending to me over the LAN. What is the best way to create an application that can both send and receive simultaneously. Do I need to consider multi threading?
Any help would be appreciated, and if anybody has code examples of something similar it would be appreciated.
Thanks,
N
Re: UDP / Sockets Design Question
Over in the CodeBank I have a thread that has a UDP class derived from one I used in a robot project to send and receive UDP packets. I believe that it does use multithreading. It may be a bit hard to find, as words of only three characters are dropped from searches, but I don't have all that many threads in the CodeBank, so you could just search on the ones I started and find it. Alternatively, do the same for the Networking forum and find the thread that has something like 7 responses, as you will find the actual class I am using in the robot project there.
Threading is a good thing, in this case, because there is only one efficient way to work with UDP that I am aware of, and it involves blocking. Basically, you get two alternatives. The first is that you block while waiting for a message to come in, which would freeze your program if it ran on the UI thread, while the second is that you continuously poll for incoming data, which would hammer your CPU while still being slow to deal with messages. Therefore, the first alternative is the most efficient, but it has to run on a different thread so that it doesn't freeze the UI. What I was doing in the classes was to take any incoming information and stick it into a Queue object, raise an event to let the UI know that a message was received, then get back to listening. The UI would dequeue the information and process it, whenever it got around to it.
As for bi-directional communication, I think I went overboard, since I was actually using two different sockets, one for inbound and one for outbound. Frankly, I think that matters very little. UDP is really really FAST, so packet collision isn't a huge problem, though they can get dropped at times. One alternative is to have the receiver echo the packet back out when it receives it. The sender can then keep sending in a loop until it receives an echo. That would ensure that the message got through, but it becomes painful if both ends can act as both senders and receivers. In UDP based games, it was generally assumed that losing a packet wouldn't really matter, as another would be along shortly, so no single packet was essential. However, if a single packet IS essential, then you have to come up with some kind of receipt system to let the sender know that the message got through. Echoing back the message is probably the best alternative.
Re: UDP / Sockets Design Question
Thanks for the info. Found http://www.vbforums.com/showthread.p...ass&highlight=
Only problem so far is that within the 'New' sub it sets the mTargetIP to broadcast. Any ideas how I specify a specific IP address? It doesn't let me for some reason.
Re: UDP / Sockets Design Question
Actually, no, I never bothered with figuring out a specific IP address solution because every use I have ever had of that UDP class is based on broadcasting. Frankly, creating a valid non-broadcast IP shouldn't be hard, but the difficulty is figuring out what IP you want to target. That would require a static IP, wouldn't it? That seems like a vanishing breed. I started out using static IPs over a decade back. At the time, it was fine, but it quickly became un-fine, and that code no longer works. I remember that the early LAN games were basically pinging out broadcast messages and listening for replies from other games to build up a list of other players. Something like that should still work: Broadcast a simple message (it could be as simple as a single byte). All listeners who receive that message should respond with their IP addresses. When you get one of those responses, you have the address. Something like that seems safer than relying on the target always having the same IP address, especially as the times they are a changin'.
Re: UDP / Sockets Design Question
Thanks again. The board I'm talking to though has a fixed IP address, managed to find an MSDN website that suggested I use the Net.IPaddress.Parse("192.168.1.1") which seemed to be OK. Still can't talk to the board yet but am making small forward steps!
Cheers,
N
Re: UDP / Sockets Design Question
Hi Shaggy Hiker, I couldn't get the code to work initially but after some tweaking managed to get a response. I had to change the following (first is from your code)
Code:
Private Sub WaitForPending()
Do
Try
Dim bHolder(MAX_PACKET_SIZE - 1) As Byte
Dim numIn As Integer
numIn = locUDP.Receive(bHolder, MAX_PACKET_SIZE, Net.Sockets.SocketFlags.None)
If numIn > 0 then
Add(bHolder)
End If
rest of code...
To
Code:
Private Sub WaitForPending()
Do
Try
Dim bHolder(MAX_PACKET_SIZE - 1) As Byte
Dim numIn As Integer
bHolder = locUDPOut.Receive(mTargetEndPoint) ' This is the line I changed
If bHolder.GetUpperBound(0) > 0 Then
Add(bHolder)
End If
rest of code...
Thanks,
N
Re: UDP / Sockets Design Question
That seems like an odd difference. I assume it has to do with you not using broadcast, whereas I was accepting anything, or it could be that the UDP classes changed since the version I used. The latter is reasonable, since when I was using them the classes were buggy, which forced me to drop down to using sockets directly at times.
Re: UDP / Sockets Design Question
I was accepting frames from anything on the local subnet but only sending to one specific address so not using broadcast. I've been using the code for a bit now and it works fine. I am a little confused why you have the queue as I just use the event to manage receipt of the udp datagrams. What benefit does the queue give you?
Re: UDP / Sockets Design Question
Hi,
I'm a bit confused with the code now. All was working fine and now all of a sudden the code in comment#6 doesn't work. I receive an exception that states "You must all the Bind method before performing this operation".
I've changed nothing and now I get this. Any ideas anyone?
If I comment out the receive method then I can send out fine and my application works. Head scratching!
Oh, I also tried the bind method and it wouldn't then let me send messages.
Hmmmmm
Thanks for any help,
N
Re: UDP / Sockets Design Question
I was using the queue because I didn't know whether or not the program that was hosting the UDP class would be ready to deal with incoming data when it was received. Some of the programs that would be receiving packets would also be running some very long-winded processes. Frankly, it was probably an overblown concern, but I thought it likely that messages would be coming fast and frequent, while some programs would be dealing with them at a more leisurely pace.
As for the error you are getting, I assume that the word is Call rather than All the Bind method, but I have never encountered that. One thing I would note, after looking at the documentation a bit, is that I must not have been using the UDPClient as the receiver, but was actually using a Socket (a lower level object). After all, UDPClient.Receive doesn't take the arguments that I was supplying, but Socket.Receive does. That's unfortunate. I remember why I used a Socket in that class: I found some sources online that talked about the UDPClient being buggy when it comes to receiving data. I don't remember that any source elaborated on what they meant by 'buggy', but they all said that it was buggy and recommended using a Socket for the receiving. You might do the same. The UDPClient exposes the underlying socket via the .Socket property, so you might try to take your client, get the socket, and use that for receiving following the design I had.
Re: UDP / Sockets Design Question
Thanks Shaggy Hiker. Will try the socket approach for receiving.