UDP Server and client

Share your advanced PureBasic knowledge/code with the community.
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

UDP Server and client

Post by RichAlgeni »

UDP Client:

Code: Select all

; udp_client.pb

EnableExplicit

InitNetwork()

Define connectionID.i
Define lenSendLine.i
Define sendLine.s
Define result.i

OpenConsole()

connectionID = OpenNetworkConnection("127.0.0.1", 9000, #PB_Network_UDP)

PrintN("UDP Networking, type 'q<enter>' to exit")

; input a line of data, or 'q' to quit

Repeat
    sendLine = Input()
    If sendLine = "q"
        Break
    Else
        lenSendLine = Len(sendLine)
        If lenSendLine
            SendNetworkData(connectionID, @sendLine, lenSendLine)
        EndIf
    EndIf
ForEver

; no close socket is needed!

CloseConsole()

End
UDP Server:

Code: Select all

; udp_server.pb

EnableExplicit

; procedure to receive UDP data

Procedure ProcessRequest(clientNumber)
    Protected result.i
    Protected *memoryLocation
    Protected memLength.i = 2048

    *memoryLocation = AllocateMemory(memLength)

    result = ReceiveNetworkData(clientNumber, *memoryLocation, memLength)

; in theory, there are no socket errors with UDP

    PrintN("Client " + Str(clientNumber) + " received " + Str(result) + " bytes: " + PeekS(*memoryLocation, result))

    FreeMemory(*memoryLocation)
EndProcedure

Define NSEvent.i
Define thisClient.i
Define keyPressed.s
Define serverNumber.i
Define portNumber.i = 9000

; initialize the network and create the server needed

InitNetwork()

serverNumber = CreateNetworkServer(#PB_Any, portNumber, #PB_Network_UDP)

OpenConsole()

PrintN("Started UDP Network Server on port " + Str(portNumber))
PrintN("Press Escape to exit")
PrintN("")

Repeat
    NSEvent = NetworkServerEvent()                 ; if we receive data, it will be indicated here

    Select NSEvent
    Case #PB_NetworkEvent_Data                     ; raw data has been received
        thisClient = EventClient()                 ; get the event client identifier
        CreateThread(@ProcessRequest(), thisClient); threaded procedure to process incoming data
    Default                                        ; some other server event, or no event occurred
        Delay(50)                                  ; sleep so we don't hammer the processor
    EndSelect

    keyPressed = Inkey()
Until keyPressed = #ESC$

PrintN("Escape pressed, press <enter> to terminate this process")

CloseNetworkServer(serverNumber)

Input()

CloseConsole()

End
Note that there is no error handling for the UDP sockets, as there normally would be for TCP. Either there is a connection and data, or not. UDP should only be used for non-critical communication purposes, but it is very much less resource intensive than TCP. If you wanted to send messages to and from processes on the same sub-net, you should have no problem.
User avatar
skinkairewalker
Enthusiast
Enthusiast
Posts: 772
Joined: Fri Dec 04, 2015 9:26 pm

Re: UDP Server and client

Post by skinkairewalker »

using multi threading on the server to receive the messages, this alleviates the weight in case of a multiplayer game that is necessary to receive messages at all times of the player's position through the udp channel?
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: UDP Server and client

Post by Kwai chang caine »

Just for information, i have try your code, and not have the full message sended 8)
I send "hello i'm kcc" and receive "hello i"

Thanks RichAlgeni for sharing 8)
ImageThe happiness is a road...
Not a destination
infratec
Always Here
Always Here
Posts: 7581
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: UDP Server and client

Post by infratec »

You need:

Code: Select all

PeekS(*memoryLocation, result, #PB_UTF8|#PB_ByteLength)
Gérard
User
User
Posts: 48
Joined: Sat Oct 17, 2015 6:00 pm
Location: France
Contact:

Re: UDP Server and client

Post by Gérard »

If the client sends qwertyuiop, the server receives qwert

If the client sends qwertyuiopqwertyuiop, the client receives qwertyuiop

The server receives only half of the string sent by the client.

The received buffer length is always correct.

I tried this, and it works.

Code: Select all

Repeat
  sendLine = Input()
  If sendLine = "q"
    Break
  Else
    lenSendLine = Len(sendLine)
    If lenSendLine
      SendNetworkData(connectionID, @sendLine, 2*lenSendLine) ; <- I double the length of lenSendLine
    EndIf
  EndIf
ForEver
@infratec:
PeekS(*memoryLocation, result, #PB_UTF8|#PB_ByteLength)
doesn't work for me.
■ Win10 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.00 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ cage sur le forum Français
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
User avatar
spikey
Enthusiast
Enthusiast
Posts: 750
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: UDP Server and client

Post by spikey »

Gérard wrote: Sun Aug 20, 2023 7:47 pm The server receives only half of the string sent by the client.
That code is a bit out of date. It was published prior to the release of PureBasic 5.50. Len returns the number of characters in a string, which isn't the same as the length of the string in bytes when a multi-byte format is in use, which is the case since 5.50.

When working with memory directly the StringByteLength() instruction should be used instead of Len(), to obtain accurate sizes.
Gérard
User
User
Posts: 48
Joined: Sat Oct 17, 2015 6:00 pm
Location: France
Contact:

Re: UDP Server and client

Post by Gérard »

My knowledge is limited, but always ready to learn.

Thanks for the info, everything is working fine now.

Gérard

Code: Select all

Repeat
  sendLine = Input()
  If sendLine = "q"
    Break
  Else
    lenSendLine = StringByteLength(sendLine)
    If lenSendLine
      SendNetworkData(connectionID, @sendLine, lenSendLine)
    EndIf
  EndIf
ForEver
■ Win10 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.00 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ cage sur le forum Français
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: UDP Server and client

Post by RichAlgeni »

Kwai chang caine wrote: Sun Aug 20, 2023 5:31 pm Just for information, i have try your code, and not have the full message sended 8)
I send "hello i'm kcc" and receive "hello i"

Thanks RichAlgeni for sharing 8)
:D
Remember, Unicode characters are two bytes, so your sending and receiving length should use StringByteLength()
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: UDP Server and client

Post by RichAlgeni »

Gérard wrote: Sun Aug 20, 2023 11:09 pm My knowledge is limited, but always ready to learn.
Awesome! Let us know if and when you need some assistance. The people here are great!
Gérard
User
User
Posts: 48
Joined: Sat Oct 17, 2015 6:00 pm
Location: France
Contact:

Re: UDP Server and client

Post by Gérard »

Hello,

Thank you very much, I would not hesitate.

Sorry for my english, i am French and i live in France.

Gérard
■ Win10 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.00 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ cage sur le forum Français
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: UDP Server and client

Post by Kwai chang caine »

RichAlgeni wrote:Remember, Unicode characters are two bytes, so your sending and receiving length should use StringByteLength()
Aaah ok :oops:
Thanks for your answer 8)
ImageThe happiness is a road...
Not a destination
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: UDP Server and client

Post by RichAlgeni »

Kwai chang caine wrote: Mon Aug 28, 2023 8:22 pm Thanks for your answer 8)
You are entirely welcome! :D
User avatar
skinkairewalker
Enthusiast
Enthusiast
Posts: 772
Joined: Fri Dec 04, 2015 9:26 pm

Re: UDP Server and client

Post by skinkairewalker »

Is there any solution for each connection to be isolated from each other? preventing that if any client sends messages wildly, it does not stop the flow of other connections?
User avatar
mk-soft
Always Here
Always Here
Posts: 6205
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: UDP Server and client

Post by mk-soft »

Sorry, for link.

The client connections must be managed. In addition, the receiving data must also be provided with separators in the receiving box of the individual connections so that the sent data can also be separated. The receive buffer for each connection is read out with ReceiveNetworkData. This is not separated according to sent data.
Since UDP is a connectionless protocol, I use the "sendto" function to send the data. This means that a distinction between server and client programme is not necessary.

UDP Local Short Text Sending
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply