UDPSocketOpen
Opens a UDP socket, which relates a certain UDP source port to a certain ID.
Syntax
UDPSocketOpen( SocketID, Port, RecvQueueSize [optional], Interface [optional])
Example #1
' A simple UDP client example sending data to another device and receiving data back
'UDP Variables
Const RecvBufferSize = 200
Public SockID As Long
Public bytesWritten As Long
Public bytesReceived As Long
Public recvDatagramStr As String * RecvBufferSize 'Leave space for null terminator
Public remoteIP As String * 100
Public remotePort As Long
Public recvTimeouts As Long 'increment this if we time out waiting for a response
Public PTemp, Batt_volt
Dim inputSize As Long
Dim recvDatagramBytes(RecvBufferSize) As UINT1 'We are receiving raw bytes back, so use UINT1
DataTable (Test,1,-1)
DataInterval (0,15,Sec,10)
Minimum (1,Batt_volt,FP2,False,False)
Sample (1,PTemp,FP2)
EndTable
'Main Program
BeginProg
Scan (1,Sec,0,0)
Battery (Batt_volt)
CallTable Test
NextScan
SlowSequence
Scan(30,Sec,0,0)
UDPSocketOpen(SockID, 0, 3) 'We are a client, so get an ephemeral port
If (SockID >= 0) Then
'Socket successfully opened
'If you were trying to send to a remote host with a domain name, you would use the DNSQuery instruction here to get the IP associated
' with that domain
'example:
'
' Public ipAddr As String * 100
' DNSQuery(Ret, ipAddr, "domain.com")
' If Ret = 0 Then
' ' We successfully resolved the domain to an IP, put rest of code in here
UDPSocketSend(bytesWritten,SockID,"10.34.10.12", 40000,"Bytes sent over UDP",19) 'size 19 to not include null character
If (bytesWritten >= 0) Then
'Successfully wrote out the message, now get a response
UDPSocketRecv(bytesReceived,SockID,recvDatagramBytes,0,remoteIP,remotePort, 500) 'Wait half a second for a response
If (bytesReceived > 0) Then
'We got a response with a non-zero payload size
If (bytesReceived >= RecvBufferSize) Then
inputSize = RecvBufferSize
'They sent us more bytes than our buffer can hold, so the input was truncated to the size of the buffer.
'Since this is just binary data, we need to add the null terminator ourselves before copying into our string. Since the buffer
'is full, we'll overwrite the last byte of data with a null terminator
recvDatagramBytes(RecvBufferSize) = &h00
Else
inputSize = bytesReceived + 1 'Add 1 for null terminator we are going to add
'We know that we have space in the buffer to add a null terminator without overwriting any data
recvDatagramBytes(inputSize) = &h00
EndIf
'Copy into string variable (this code makes the assumption that all of these bytes are printable characters, which is not an
'assumption actual application should make)
MoveBytes(recvDatagramStr, 0, recvDatagramBytes, 0, inputSize)
ElseIf (bytesReceived = -1) Then
'We timed out waiting for a response
recvTimeouts += 1
EndIf
EndIf
UDPSocketClose(SockID) 'If a socket is successfully opened, it will stay open until it is closed
EndIf
NextScan
EndSequence
EndProg
Example #2
'CR1000X Series Datalogger
'Simple UDP Server application that echos back data that is sent to it
'UDP Variables
Const ServerPort = 40000 'UDP Port the server listens on
Const RecvQueueSize = 10
Const RecvBufferSize = 200
Const PrefixSize = 8
Const SendBufferSize = RecvBufferSize + PrefixSize
Public SockIsOpen As Boolean = FALSE 'Server is listening
Public SockID As Long
Public bytesWritten As Long
Public bytesReceived As Long
Public remoteIP As String * 100
Public remotePort As Long
Public initErrorFlag As Boolean = FALSE 'let user know opening the port failed
Public recvErrorFlag As Boolean = FALSE 'let the user know we had an error while receiving
Public recvTimeouts As Long 'increment this if we time out waiting for a response
Public PTemp, Batt_volt
Public recvDatagram(RecvBufferSize) As UINT1
' e c h o - >
Dim sendBuffer(SendBufferSize) As UINT1 = { &h65, &h63, &h68, &h6F, &h20, &h2D, &h3E, &h20 }
Dim inputSize As Long
DataTable (Test,1,-1)
DataInterval (0,15,Sec,10)
Minimum (1,Batt_volt,FP2,False,False)
Sample (1,PTemp,FP2)
EndTable
BeginProg
Scan (1,Sec,0,0)
Battery (Batt_volt)
CallTable Test
NextScan
SlowSequence
Scan (1,Sec,3,0)'Check every second, so messages do not build up
If NOT SockIsOpen Then
UDPSocketOpen(SockID, ServerPort, RecvQueueSize, 1) 'We are a server, so choose a port. Also, set recv queue higher
'so we do not drop messages. Bind to ethernet
If (SockID >= 0) Then
SockIsOpen = TRUE
Else
initErrorFlag = TRUE 'Just let the user know.
EndIf
EndIf
If SockIsOpen Then
'Socket successfully opened
UDPSocketRecv(bytesReceived,SockID,recvDatagram,0,remoteIP,remotePort)
If (bytesReceived >= 0) Then
' We received a datagram. Use the remoteIP and remotePort parameters to send a response back to the device that sent us the datagram
'Copy into send buffer (we are echoing the data back with a prefix of the ASCII bytes 'echo -> ')
If (bytesReceived >= RecvBufferSize) Then
inputSize = RecvBufferSize 'They sent us more bytes than our buffer can hold, so the input was truncated to the size of the buffer.
Else
inputSize = bytesReceived
EndIf
MoveBytes(sendBuffer, PrefixSize, recvDatagram, 0, inputSize)
UDPSocketSend(bytesWritten,SockID,remoteIP,remotePort,sendBuffer,PrefixSize + inputSize) 'A real application should check for an error
ElseIf (bytesReceived < -1) Then
recvErrorFlag = TRUE 'Just let the user know an error happened. A real application should check error codes
EndIf
EndIf
NextScan
EndSequence
EndProg
Remarks
UDPSocketOpen() opens a UDP "socket" which relates a certain UDP source port to a certain ID. This instruction returns an ID that can be passed to other UDPSocket type functions to send and receive data using this source port. UDP servers and clients do not really exist in the same way as with TCP, since UDP is connectionless, but generally a client will pass 0 for the source port, so that the operating system will assign it an ephemeral port. Servers (who are listening for connections from multiple remotes) will generally choose to specify a well known or registered port to listen for incoming datagrams and send response datagrams on.
Parameters
SocketID
A variable that holds the Socket ID that can be passed to other UDPSocket functions to operate on the socket or an error code. If negative, an error occurred (socket not opened). The values that can be returned are:
| Code | Description |
|---|---|
| >=0 | Successful. This is the socket ID. |
| -1 | Failed to allocate UDPSocket. |
| -2 | Requested port in use. |
| -3 | Limit of open ports reached. |
| -4 | Port out of range. |
| -5 | Invalid interface. |
Type: Variable of type Long
Port
A non-ephemeral port to bind this socket to (1 - 49151). If 0 is passed, the operating system will bind this socket to an ephemeral port.
Type: Constant or Variable of type Long
Optional Parameters
RecvQueueSize
Specifies the maximum amount of messages that will be queued up for UDPSocketRecv on this particular socket. If maximum queue size is reached, incoming packets will be discarded. Thus, the user is encouraged to call UDPSocketRecv often. This parameter defaults to 5. If you are not interested in receiving any data on this socket, set this parameter to 0 to stop any incoming data from being buffered up.
Type: Constant or Variable of type Long
Interface
Specifies an interface to bind this socket to. By default, this socket will send and receive on all active interfaces and be affected by the IPRoute() instruction. If non-zero (this socket is bound to an interface), this socket will not be affected by IPRoute.
| Value | Description |
|---|---|
| 0 | Default behavior |
| 1 | Internal Ethernet. |
| 2 | CS I/O Interface(1) (NL201 by default) |
| 3 | CS I/O Interface(2) (NL241 by default) |
| 4 | Internal Wi-F |
| 5 | PPP |
Type: Constant or Variable of type Long