User Tools

Site Tools


Sidebar

Network and communication

k24:k24.1:k24.1.3:k24.1.3.1:start

24.1.3.1 UDPSocket Projects

In this chapter you will be introduced to three projects that use the UDPSocket class.

  • The first project is a server-client programme. It uses a UDP server to provide a quote service that is used by UDP clients. They can request short and long quotations.
  • The second project retrieves the current time as a datagram from an NTP time server on port 123 and outputs it formatted.
  • From the source code of Gambas comes a server-client-program, which has been adapted especially with regard to the GUI. The UDP server provides the service of sending a text sent to it back to the client as reversed text - the character string 'stock' becomes 'regaL', for example.

For the second project, the source code is given in full in the chapter. All three project archives can be found in the download area.

24.1.3.1.1 Project 1 - Quote Service

At https://wiki.pythonde.pysv.org/UDP-Broadcasts you will find in the text

“UDP broadcasts can be used to allow client and server to find each other on a subnet without first knowing which hosts they are running on. The server does this by opening a socket that listens on a specific port. A client can then send a UDP broadcast on that port to all hosts on the subnet, to which the server can respond.”

A good hint on how to implement a broadcast on the subnet:

[1] Public Sub btnBroadcast_Click()
[2]
[3]     Dim sMessage As String
[4]
[5]     txaShowQuote.Clear()
[6]
[7] '-- Es wird ein UDP-Socket erzeugt
[8]     UDPClientSocket = New UDPSocket As "UDPClientSocket"
[9]
[10]     If UDPClientSocket.Status <= Net.Inactive Then
[11]        UDPClientSocket.Broadcast = True
[12]        UDPClientSocket.Port = 0 ' Standard-Port für einen UDP-Client
[13]        UDPClientSocket.Bind()
[14]    '-- Standard-Subnetz-Maske im Klasse-C-Netz => 255.255.255.0
[15]        txbTargetHost.Text = sNetzAdresse & ".255" ' IPv4-Broadcast-IP-Adresse
[16]    '-- Ziel-Adressierung: Host und Port
[17]        UDPClientSocket.TargetHost = txbTargetHost.Text
[18]        UDPClientSocket.TargetPort = txbPort.Text
[19]
[20]        Inc Application.Busy
[21]    '-- Ein Datagramm wird an das adressierte Ziel (Server) gesendet
[22]        Write #UDPClientSocket, "broadcast", Len("broadcast")
[23]        Dec Application.Busy
[24]        UDPClientSocket.Broadcast = False
[25]     Endif
[26]
[27]     bBroadcasted = True
[28]
[29]     Wait 0.5
[30]     If Not txaShowQuote.Text Then
[31]       sMessage = "\n\nDer Rundruf wurde von keinem UDP-Socket auf Port "
[32]       sMessage &= txbPort.Text & "\nim lokalen Netzwerk mit der Netzadresse "
[33]       sMessage &= sNetzAdresse & " quittiert!" ""
[34]        LogMessage(sMessage)
[35]        btnClose.SetFocus()
[36]     Endif
[37]
[38] End

Comment:

  • Line 10: Only for a UDPSocket state < 0 you can set the port.
  • With UDPClientSocket.Broadcast = True in line 11 and the target addressing in line 17: UDPClientSocket.TargetHost = txbTargetHost.Text (Broadcast.IP address) you specify that all datagrams are sent to all hosts in the subnet.
  • The text 'broadcast' sent by the client can be evaluated by the started server - if it is bound on the assigned port. It then sends back a comment that also contains the host name. From the response from the server, the client can read the IP address and the port to which the server is bound.
  • In UDP socket programming, port 0 has a special meaning - especially in unixoid operating systems - because port 0 is a reserved port in UDP networks. The command sequence in lines 12 and 13
  1. UDPClientSocket.Port = 0
  2. UDPClientSocket.Bind()
  • is used to dynamically request from the system the next available, currently unused port number on the subnet and bind the socket to that port number and open that port. This, together with the IP address, enables unique destination addressing in lines 17 and 18. IP services that run in the same subnet and therefore under the same IP address are identified by their (different) port number! If you start the UDPServer and the UDPClient on the same computer, for example under 127.0.0.1 (localhost) or, as in the case of the author's computer, under 192.168.2.103 (mint-183), then it will not surprise you that the client and server communicate with different port numbers. This becomes clear in the following two illustrations:


Figures 24.1.3.1.1: Communication UDPServer ↔ UDPClient

After the acknowledged broadcast, the client knows of an active server on 192.168.2.103 with port 32340. Furthermore, it can be seen that the client is communicating with the server on the same IP address but on port 56644 assigned by the system.

In order to use the server's citation service and not just receive a message that the requested service is currently unavailable, you should install the (German) collection of citations for the server:

sudo apt install fortune-mod	        ' Programm
sudo apt-get install fortunes-de	' Quote collection


Figure 24.1.3.1.2: Server client programme

The following is a test description for one client and two servers:

  • First, a client and a server are started on computer A and another server on a computer B (laptop). The quote collection is not installed on the laptop.
  • Then a broadcast is started by the client to explore whether there are communication partners on port 32340 in the local network. The broadcast is made with broadcast IP for class C networks that are not decomposed into subnets. Their default subnet mask is 255.255.255.0.
  • Both servers answer and also give the host name in each case. The client thus knows the IP address of both servers, which is required for further communication.
  • The client is then started and communication - in this case the use of the quote service from both servers - can begin.
  • For example, the IP address of the server on computer B is specified and a long quote is retrieved with -l (long). The server responds and informs that the requested service is currently unavailable. At least that's something - you are properly notified.
  • After changing to the IP address of the UDP server on computer A, a short quote is retrieved with -s (short). The quote is delivered by the server, logged by the server and displayed in the client.
  • Finally, the client is stopped. Both servers do not notice this - how could they, because with UDP there are no controlled connections between the communication partners.

24.1.3.1.2 Project 2 - Time Service

In the second project, a client uses the time service of a time server on the reserved port 123. For this purpose, the client sends an empty datagram to the server. The server acknowledges the receipt of the empty datagram by sending a datagram whose content contains the current time:


Figure 24.1.3.1.3: Client on port 123

The source code for the client is given in full:

[1] ' Gambas class file
[2]
[3] Public UDPClient As UdpSocket
[4]
[5] Public Sub Form_Open()
[6]     UDPClient = New UdpSocket As "UDPClient"
[7] '-- Initialisierung des UDP-Sockets
[8]     UDPClient.Port = 0
[9]     UDPClient.Bind()
[10] '-- Vollständige Adressierung:
[11] '-- TimeServerURL: ptbtime1.ptb.de -> IP: 192.53.103.108
[12]     UDPClient.TargetHost = "192.53.103.108"
[13] '-- Für NTP ist der UDP-Port 123 reserviert.
[14]     UDPClient.Targetport = 123
[15]     FMain.Caption = "Datagramm vom NTP-Server `ptbtime1.ptb.de` (Port 123)"
[16] End
[17]
[18] Public Sub UDPClient_Read()
[19]
[20]     Dim sData As String
[21]     Dim i, iVSeconds As Integer
[22]     Dim VSeconds As Long
[23]     Dim CurrentDate As Date
[24]
[25] '-- Auslesen des Zeit-Datagramms vom NTP-Server - gespeichert in `sData`
[26]     Read #UDPClient, sData, Lof(UDPClient)
[27] '-- Auswerten des Zeit-Datagramms -> https://de.wikipedia.org/wiki/Network_Time_Protocol
[28]     For i = 17 To 20
[29]       VSeconds += Asc(Mid$(sData, 37 - i, 1)) * 256 ^ (i - 17)
[30]     Next
[31]     iVSeconds = VSeconds - 2208988800 ' - System.TimeZone
[32]     CurrentDate = DateAdd("01/01/1970", gb.second, iVSeconds)
[33] '-- Formatieren des aktuellen Zeitstempels
[34]     lblDateTime.Text = Format(CurrentDate, "dd.mm.yyyy hh:nn:ss")
[35] End
[36]
[37] Public Sub UDPClient_Error()
[38]
[39]   Select Case UDPClient.Status
[40]     Case Net.CannotBindSocket
[41]       Message.Error(("Unable to Bind to that port"))
[42]     Case Net.CannotCreateSocket
[43]       Message.Error(("System does not allow to create a socket"))
[44]     Case Net.CannotRead
[45]       Message.Error(("Error Sending Data"))
[46]     Case Net.CannotWrite
[47]       Message.Error(("Error Receiving Data"))
[48]   End Select
[49] End
[50]
[51] Public Sub btnGetTime_Click()
[52] '-- Der NTP-Server reagiert auf den Empfang eines leeren Datagramms mit
[53] '-- dem Senden eines Datagramms, dessen Inhalt den aktuellen Zeitstempel enthält.
[54]
[55] '-- Abschicken eines leeren Datagramms an den NTP-Server -> ' # + 47 mal Nul (=> Chr(0))
[56]     Write #UDPClient, Chr$(35) & String$(47, Chr$(0)), 48
[57] End
[58]
[59] Public Sub Form_Close()
[60]   If UDPClient Then
[61]      If UDPClient.Status > 0 Then UDPClient.Close()
[62]   Endif
[63] End

24.1.3.1.3 Project 2 - Reverse Service

The third project is based on a project from the Gambas source code that demonstrates the use of the UDPSocket class. The service consists of a string sent by a client being sent back by the server as a reverse string to the client that requested the service:


Figure 24.1.3.1.4: Project 3

Note the different port numbers of client A and of client B in the middle picture, which are used to realise the communication with the server!

Download

The website uses a temporary session cookie. This technically necessary cookie is deleted when the browser is closed. You can find information on cookies in our privacy policy.
k24/k24.1/k24.1.3/k24.1.3.1/start.txt · Last modified: 18.06.2022 (external edit)

Page Tools