Link to home
Start Free TrialLog in
Avatar of GivenRandy
GivenRandy

asked on

UDP Server with Multiple Clients -- Simultaneously

I have a UDP Server that can work with multiple clients using Winsock control (the clients are on the same machine but different port numbers). However, it does not work with them simultaneously. It seems to only communicate with one at a time. I want the control to respond to each client's request, but it does not seem to be doing that.
Avatar of Leo71
Leo71

I don't really get it (sometimes I'm a little bit slow ;-) ).
How does the request of the clients look like? Do you mean your server also listens on different ports?
Do you have a own task for every port you listen on, or how does it work?

Regards
Leo
Avatar of GivenRandy

ASKER

The server listens one on port while the clients are on two, or more others. I will try to provide more detail Monday, if that doesn't help.
So I guess you listen on one port and for every client request you some how resolve the client IP+port (either you just take the IP and port the request was sent from or it's part of the request protocol), and for every client IP+port you create an thread (with it's own socket), that serves that request.
Or do you have only one server socket where you change the client address of the socket for every request you answer?

Whatever you have I see only one way that you can transfer simultanous:
For every client an own thread with own socket, that have of course different server ports (which is choosen automatically by the operating system I think).
If this is, what you have implemented and it still does not work the thing get's interresting.
If not please explain how your server responses to the requests so that it should be able to make simultanous transfers.
Regards
Stephan
I should mention: I have almost no clue about VB. But at an idea about win sockets. I used them with VC. So the specific functions my be a little different, but the concept should be the same, as wsock32 is the same and MS professes in different places, that they followed the implementation of Berkley university.
Any others ?
If no more feedback, I will have to ask for deletion.  :(
Well u can ask for deletion, or you can describe more detailed how your programm works (or post code samples).
I still don't know if you start a new task for every connection that you got from your listen socket or if you try some other aproach.

Regards
Leo
Make three projects and executables: Server, Client1 and Client2.

For Server. Add textbox "txtSend", textbox "txtReceived", commandbutton "cmdSend" and winsock "sckServer" to the form. Set "sckServer" Protocol to sckUDPProtocol. Use this code in the form:

---
Option Explicit

Private Sub cmdSend_Click()
    sckServer.SendData txtSend.Text
End Sub

Private Sub Form_Load()
    With sckServer
        .RemoteHost = "localhost"
        .RemotePort = 1002
        .Bind 1001
    End With
End Sub

Private Sub sckServer_DataArrival(ByVal bytesTotal As Long)
    Dim strData As String
   
    sckServer.GetData strData
    txtReceived.Text = txtReceived.Text & strData & vbCrLf
End Sub
---

For Client1. Add textbox "txtSend", textbox "txtReceived", commandbutton "cmdSend" and winsock "sckClient" to the form. Set "sckClient" Protocol to sckUDPProtocol. Use this code in the form:

---
Option Explicit

Private Sub cmdSend_Click()
    sckClient.SendData txtSend.Text
End Sub

Private Sub Form_Load()
    With sckClient
        .RemoteHost = "localhost"
        .RemotePort = 1001
        .Bind 1002
    End With
End Sub

Private Sub sckClient_DataArrival(ByVal bytesTotal As Long)
    Dim strData As String
   
    sckClient.GetData strData
    txtReceived.Text = txtReceived.Text & strData & vbCrLf
End Sub
---

For Client2. Add textbox "txtSend", textbox "txtReceived", commandbutton "cmdSend" and winsock "sckClient" to the form. Set "sckClient" Protocol to sckUDPProtocol. Use this code in the form (note the change for the port number, from 1002 to 1003):

---
Option Explicit

Private Sub cmdSend_Click()
    sckClient.SendData txtSend.Text
End Sub

Private Sub Form_Load()
    With sckClient
        .RemoteHost = "localhost"
        .RemotePort = 1001
        .Bind 1003
    End With
End Sub

Private Sub sckClient_DataArrival(ByVal bytesTotal As Long)
    Dim strData As String
   
    sckClient.GetData strData
    txtReceived.Text = txtReceived.Text & strData & vbCrLf
End Sub
---

Compile all of those to executables (Server, Client1, Client2).

+ start Server
+ start Client1
+ start Client2
+ from Client1, type "Client1" and select "Send"
+ on Server, verify that you see the message
+ from Server, type "Server" and select "Send"
+ on Client1, verify that you see the message
+ on Client2, verify that you do NOT see the message
+ from Client2, type "Client2" and select "Send"
+ on Server, verify that you see the message
+ from Server, type "Server" and select "Send"
+ on Client2, verify that you do NOT see the message
+ on Client1, verify that you see the message

The last two are not what I want (I want the reverse).
Indeed it looks a little different than VC (the word listen does not even show up :) ). But as far as I understand it:
Server:   Listens on 1001, sends always to 1002 (client 1)
Client 1: Listens on 1002, sends always to 1001 (server)
Client 2: Listens on 1003, sends always to 1001 (server)

I did not see code, that changes the RemotePort of the server (but I also saw that in VB many thing work implicitly ;-) ).
I guess you need something like Socket.RemoteEndPoint to determine which client has sent the last message and adjust sckServer.RemotePort to that client port.
I'm afraid that since UDP is a connectionless protocoll Socket.RemoteEndPoint does not work. That means you would have to change to TCP.

A also noticed that I understood you wrong from the beginning. I really thought you want to transmitt data to your clients concurrently. Thats why I started talking of this multiple thread stuff.

If you want to change to TCP I'm sure, we can work this out, even if I can not programm VB.

Regards
Leo
>I guess you need something like Socket.RemoteEndPoint
>to determine which client has sent the last message
>and adjust sckServer.RemotePort to that client port.

Right, something like that.

Changing to TCP is not an option in this case -- am communicating with another device that only does UDP (and probably does it right).
I think I will close this one and open another with a better description ... and more points.
Maybe it goes infront of the queue then :).
Did you try Socket.RemoteEndPoint, just for fun?
The description sais it works for connections that support it. Since UDP is a connectionless protocol that means it does not work. But there's still a 1% chance left that it works on IP level. Unfortunately I'm pretty sure that even if it would be possible it's not used by the socket object.
The socket object will propably return the last Endpoint it was connected to (with a connection orientated protocoll) or nothing if no connect was made.

Whith other words: There's propably no way to do it. Not for UDP. Not if the client port/IP is not part of the client request.
Sorry.

You're from Europe?
Is it necessary, that both clients send the request to the same server port?
Yes.
A request for refund has been made.  Experts please leave your comments for this question's disposition within 72 hours.  I will return at that point.  Without feedback I intend to PAQ with refund.  Thanks

SpideyMod
Community Support Moderator @Experts Exchange
I undestood this is not an option, because you can not change the behaviour of your client. So I discarded the idea.
If you can it's no problem.
Right -- it is not changing the client, but the server.
ASKER CERTIFIED SOLUTION
Avatar of SpideyMod
SpideyMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Private Sub cmdSend_Click()
   sckClient.SendData txtSend.Text
End Sub

looks different for me than

Private Sub cmdSend_Click()
 sckClient.SendData sckClient.LocalPort & "::" & txtSend.Text
End Sub

Thats what I ment with client address is part of the protocol, in my second comment. But as I told you I dropped that approach.
Nevertheless I could not have told you how to write it in basic.

Regards
Leo