Embarrasingly simple requirement that I can’t make work! Using Net+OS patched to a few months ago, on a 9P-9215. I want to have a single socket set up to receive all UDP packets with a specific port number. All the non-Digi resources indicate that this is as simple as opening a socket, binding it to the port number (and, optionally, a specific local address) and calling recv() or recvfrom(). However recv() always fails with error 128 - “Socket is not connected”. I found the Digi documentation on UDP sockets to be a little sparse, and it didn’t always tie up with non-Digi sources.
I’ve stripped most of the error checking from the following code (since no errors):
#define SNMP_MESSAGE_PORT 161
#define NET_RX_BUFFER_SIZE 512
SOCKET mainSock;
struct sockaddr_in rxAddr;
int errCode;
mainSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); // Create the socket to start - using UDP
/* Set blocking socket explicitly, to be certain */
int sockOption = 1;
setsockopt(mainSock, SOL_SOCKET, SO_BIO, (char *)&sockOption, sizeof(sockOption));
rxAddr.sin_addr.s_addr = htonl(localIp); // also used INADDR_ANY
rxAddr.sin_family = AF_INET;
rxAddr.sin_len = sizeof(rxAddr);
rxAddr.sin_port = htons(SNMP_MESSAGE_PORT);
bind(mainSock,(struct sockaddr *)&rxAddr, sizeof(rxAddr));
struct fd_set masterReadSet;
struct fd_set readSet;
int rxLen;
static char rxBuffer[NET_RX_BUFFER_SIZE]; // Fixed UDP receive buffer
/* Pre-calculate the set of sockets for select() */
FD_ZERO(&masterReadSet);
FD_SET(mainSock, &masterReadSet);
for (;
{
readSet = masterReadSet;
errCode = select(mainSock + 1, &readSet, NULL, NULL, NULL);
if (errCode == 0) // 0 is a timeout - might happen after a very long time - can ignore.
{
continue;
}
if (errCode < 0) // -1 is an error.
{
errCode = getErrno(); // Always error code 128 here
continue;
}
/*
- Now see if we have any receive data to process
*/
if (FD_ISSET(mainSock, &readSet))
{
rxLen = recv(mainSock, rxBuffer, NET_RX_BUFFER_SIZE, 0);
if (rxLen <= 0)
{ // No data - some sort of network error (or could potentially get empty packet)
errCode = getErrno();
continue;
}
tx_thread_sleep(1);
}
When I send a UDP packet to the device, the select() duly triggers, but recv() always gives an error (apparently without blocking; if I comment out the select(), recv() completes immediately).
I’ve tried a different port number, among other things.
Am I missing something really obvious?