UDPSocketSend
Sends a UDP datagram to a remote device via an opened UDP Socket.
Syntax
UDPSocketSend( BytesSent, SocketID, IPAddr, Port, Payload, PayLoadLen)
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 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
Example #3
'CR1000X Series Datalogger
'Simple UDP Server application that echos back data that is sent to it
'This example is very similar to Example #2 but uses the blocking functionality of the UDPSocketRecv() Timeout parameter.
'It is not generally recommended to use this functionality, because it could theoretically be waiting for data to come in
'forever. However, if the only thing the program is doing is listening for incoming UDP datagrams and it doesn't matter how often the 'datalogger checks for a new UDP datagram, the blocking functionality is a good option. In this case, the OS is choosing how often to poll for 'incoming data, not the programmer, and it checks many times per second to make sure it provides UDP datagrams processed by the datalogger's 'TCP/IP stack to the program within milliseconds of when they are received.
'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 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
While 1
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,-1)
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
Wend
EndSequence
EndProg
Remarks
Sends a UDP datagram to a remote device via an opened UDP Socket. (It will be sent with the source port of that socket.)
Parameters
BytesSent
Returns the number of bytes written. If negative, an error occurred. The values that can be returned are:
| Code | Description |
|---|---|
| >=0 | Successful send a datagram with a payload of this many bytes. (It is possible to send a UDP datagram of 0 bytes that will just include the UDP header.) |
| -1 | Failed to send. (Network interface may be down.) |
| -2 | Socket not initialized or was closed. (The only way this will be closed is if you call UDPSocketClose.) |
| -3 | Invalid IP address. |
| -4 | Invalid PayloadLen. |
| -5 | Failed to allocate send buffer. |
|
-6 |
Invalid SocketID. |
Type: Variable of type Long
SocketID
Socket ID returned from a call to UDPSocketOpen().
Type: Constant or Variable of type Long
IPAddr
The IP address of the device to send this datagram to.
Type: Constant or Variable of type String
Port
The port to send this datagram to.
Type: Constant or Variable of type Long
Payload
The contents of the packet.
PayloadLen
The length of the payload in bytes. If payload length is 0, a zero-length UDP packet is sent.
Type: Constant or Variable of type Long