Results 1 to 11 of 11

Thread: udp?

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    udp?

    I'm converting my project from TCP to UDP.

    while there were plenty of UDP examples on the net that i could learn from, i'm finding that multi-threaded client/server UDP examples are a bit rare.

    i can't even find the equivalent of TCPlistener for UDP.

    the only lonely remark i found was that the UDPclient is "a bit buggy, you should use Sockets instead"

    if anyone can point out some educational links on multi-threading UDP in VB.NET then I'd be very grateful.

    (note to self- update your siggy)
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: udp?

    There is no equivalent of the TcpListener. The whole point of UDP is that it's connectionless, so you don't need a listener to establish a connection. At the server end, you simply create a UdpClient and call Receive (blocking) or BeginReceive (non-blocking). At the client end, you simply call Send (blocking) or BeginSend (non-blocking). As you want this all to be multi-threaded, you should use the non-blocking calls. Have a look at the MSDN documentation for the UdpClient.BeginSend and .BeginReceive methods and that's pretty much all you need.

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: udp?

    that little info you gave me actually made a huge difference.

    could you help me with this code?

    vb Code:
    1. Private Structure svrSocket
    2.         Dim SendBufferSize As Integer
    3.         Dim ReceiveBufferSize As Integer
    4.         Public Sub New(ByVal port As Integer)
    5.             Dim Server As New UdpClient(port, AddressFamily.InterNetwork)
    6.         End Sub
    7.         Public Property NoDelay As Boolean
    8.             Get
    9.                 Return svrSocket.server.nodelay
    10.             End Get
    11.  
    12.             Set(ByVal value As Boolean)
    13.                 svrSocket.server.nodelay = value
    14.             End Set
    15.         End Property
    16.  
    17.  
    18.  
    19.     End Structure

    trying to figure out how to implement NoDelay properly.
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: udp?

    You've got some issues there. First, your constructor creates a UdpClient object but only assigns it to a local variable. That local variable ceases to exist when the constructor completes so you lose your only reference to that UdpClient object so you can never use it. If you want to use the object later then you need to assign it to a variable that will exist later, i.e. a member variable. In your NoDelay property you appear to be trying to refer to a 'server' variable that doesn't exist. That is presumably where you expect the UdpClient to be, so you need to declare that variable and assign the UdpClient to it.

    Second, in your NoDelay property you are using the svrSocket type to access the 'server' field. It's not a field of the type you want but a field of this specific instance of the type. How do you refer to the current instance? Me.

    Finally, I'd recommend not using silly names like 'svrSocket'. If you can use the whole word "Socket" then why can't you use the whole word "Server"? Type names should always start with an upper case letter, so 'ServerSocket' is what that type should be named. That said, it's not really a socket is it? It is obviously intended to work at a higher level than a socket so it should have a name that reflects that. In my Asynchronous TCP thread in the CodeBank, I had classes that were supposed to use TcpClients to send and receive messages. The outside world didn;t have to actually know that TcpClients were being used so the names, 'MessageServer' and 'MessageClient', didn't include anything about that. The names reflected the purpose, not the implementation.

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: udp?

    TCP was so much easier.

    I can tell a UDP to connect but i can't ask it if
    udpclient.connected = boolean ?

    i can picture the answer already:
    "no, because it's an unreliable connectionless protocal"
    then why is there a connect!?!?


    there has to be a more in-depth tutorial on the net somewhere, but i already searched for 2 days on "the Google."

    ugh.
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: udp?

    You seem to be completely missing the point of UDP. It is a connectionless protocol. Of course you can't check whether a UDP client is connected because a UdpClient is never connected. If you need an actual connection then you should be using TCP and not UDP. UDP is simpler than TCP because of the fact that it is connectionless.

    The Connect method DOES NOT CREATE A CONNECTION. All it does is specify a default remote host. The reason that you would use Connect is that it will save you specifying the remote host each time you call Send. If you're going to send data to the same host multiple times, it is easier to call Connect once and then not specify a remote host when calling Send than it is to specify the same remote host each time you call Send. That's all Connect is for: to save you having to specify the host every time you call Send.

    I would question exactly why you are using UDP in the first place. As I said, if you want a connection then you should be using TCP. You would only use UDP specifically because you don't want a connection. If you're doing this to learn how UDP works then I suggest that do some reading on what UDP is and isn't first, because you are expecting it to do something that it can't do because it was never designed to do it. It's like you have decided to ride a bicycle instead of a motorbike and then you're surprised that you have to pedal.

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: udp?

    I would question exactly why you are using UDP in the first place. As I said, if you want a connection then you should be using TCP. You would only use UDP specifically because you don't want a connection. If you're doing this to learn how UDP works then I suggest that do some reading on what UDP is and isn't first, because you are expecting it to do something that it can't do because it was never designed to do it. It's like you have decided to ride a bicycle instead of a motorbike and then you're surprised that you have to pedal.
    I'm creating a multiplayer FPS.
    in VB6 tcp sockets worked fine.
    but in .NET the TCP is gobbling up Server CPU like crazy when going beyond Lan.

    I'm hoping UDP can solve that problem because it "Fire's it off then forgets it"

    but that brings up other issues such as "When do you know a client timed out when you can't check to see if connection is lost?" etc...

    It's not that i'm surprised that i have to pedel the bicycle - it's that the seat seems to be on the handlebars.
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: udp?

    One possible option:

    When you receive a message from a client, check whether there is an existing session. If there isn't, create one and start a Timer for it. If and when that Timer raises its Elapsed event, the session has timed out and you can remove it. If there is an existing session for the client when a message is received, stop and restart the Timer, thus resetting the timeout period.

    Another possible option:

    Each time a message is received from a client, create a session if one does not already exist or else update the last message time for the session. Have a single Timer that runs constantly and, each time it raises an Elapsed event, check every session and remove those for which the time since the last message is greater than or equal to the timeout period.

    In either case, you might have a client send a "heartbeat" message to keep its session alive as long as it's running, even if it's not sending any other data.

  9. #9
    Junior Member
    Join Date
    Jul 2006
    Location
    Warner Robins GA
    Posts
    27

    Question Re: udp?

    Thanks jmcilhinney. Very clear and usable responses to this thread. I am just learning UDP and TCP and I appreciate how you helped Waxy here. Between you both, are there any tutorials or books that you both may recommended to help me have a complete understanding of this programming logic? Thanks.

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: udp?

    Quote Originally Posted by ImDaFrEaK View Post
    Thanks jmcilhinney. Very clear and usable responses to this thread. I am just learning UDP and TCP and I appreciate how you helped Waxy here. Between you both, are there any tutorials or books that you both may recommended to help me have a complete understanding of this programming logic? Thanks.
    I have nothing specific to recommend I'm afraid. I know what I know simply by reading bits and pieces and experimenting a bit. I pretty much always start with the documentation for the types and members I want to use, then spread the net from there.

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: udp?

    Over in the .NET CodeBank, I have an extraction of a UDP class that comes from some robot work. The actual class, along with a variety of discussions on it can be found by searching for threads started by me in the Networking section.

    UDP has a long history in peer-to-peer gaming because it is ideal for fast communications of small amounts of data. However, if you are used to TCP, where you created connections and always expected there to be somebody on the other end, then UDP will be a bit alien. The best analogy I have seen is that TCP is like a phone call: Nothing happens unless somebody picks up on the other end, at which time there is a connetion between the sender and the receiver. UDP, on the other hand, is like the post office: You drop off a message which is addressed to somebody, but you can't be sure that there is anybody at the address, and you can't even be sure that the message got through (it could be lost in the mail). Oddly, and quite unlike the post office, a UDP packet can actually get through more than once, though I have never seen it happen in practice.

    This requires a different way of thinking about UDP. Ideally, all of your messages are small enough to fit into a single packet (size is hard to determine, but a could KB or smaller, should be safe), and it shouldn't matter whether the packet got through or not. This is normally good enough in games where what is typically being sent is something like the change in location of some agent in the game. If one change is lost, it really doesn't matter, because another change will be coming along very soon. For this reason, no one packet is normally considered critical to the game. However, since any packet COULD be lost, if there is a packet that is critical, then there has to be some kind of receipt acknowledgement message returned. Quite often, I log the outgoing message, and have the receiver re-send the exact same message. When the sender receives back the same message it just sent out, then it knows that it was received. This is a slippery slope, though, because what happens if the acknowledgement packet is lost? In practice, I haven't seen packets get lost on a LAN, but it can certainly happen, and you have to think about that.

    Another advantage for UDP is that it is so easy to broadcast messages. In the case of the robot code, the brain of the robot is spread across several computers. Each module (there could be more than one running on any computer) should receive all messages from elsewhere in the brain, and decide for itself whether it needs to do anything with the information. Any module can also initiate messages. This is pretty common in multi-player games, where any one system would be sending out movement packets for all others to see, and consuming all movement packets from other systems. Using TCP, this would require that there either be connections between all systems, or a central clearing house (server) that would receive all messages and re-send them to all other systems. That creates a bottleneck, and isn't as fast anyways (because TCP is slower than UDP).

    So, you end up with a trade-off. TCP is decidedly more popular than UDP, and it is often easier to use. Being able to assume that your whole message, largely independent of the size of the message, will get through to the destination completely, and in the order it was sent, makes TCP quite a bit more comfortable for most situations. But UDP is faster, broadcasts more easily, and is pretty simple (no connections needed), so it has its uses.

    As for 'losing a connection', you can't know. One thing I have done in the past is to run a counter on all outgoing messages. Anytime an incoming message is received, I clear the counter. If the counter gets above N, I assume the other system is no longer listening, or the network is down. Exactly where N should be set depends on how the system should work. In most of my cases, messages are frequent, and are often being echoed back, in which case N can be quite low. If one system sends often, and the other system sends very rarely, then N needs to be quite high for the sender, and quite low for the receiver, but I have never encountered that situation.

    Another solution that I have used is to have a timer ticking every 1-5 seconds. When the timer ticks, send out a message. Then you can either have all other systems echo the message back, or not (I think I chose NOT). The idea is that there is no single server sending out these messages. All systems are equal, so all are running the timer, and all are sending the message periodically. Any system receiving the message knows that the network is functioning (because it is getting messages), and that at least the sender is still on line. I've done this in systems where the user could be idle for many minutes at a time, and therefore each system might be sitting without receiving anything for many minutes. The timer, ticking once every 5 seconds, kept both sides from wondering whether the silence was a case of inactivity, or was something worse. Remember, UDP packets are tiny and FAST, so adding something else in there like that usually has no negative impact.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width