Trying to send a short message using TCP or UDP sockets and then read the short response through the same socket

I am using Dynamic C V9.62 to develop on a BL2600 SBC.

Essentially, I want to open a socket to a remote instrument (IP:PORT), send a short message to that instrument, and then read the instrument’s reply through the same socket. I am new to socket programming and none of the examples I tried gave me enough insight on how to do this.

Thanks in advance for any assistance.

UDP Server: C:\DCRABBIT_10.72\Samples cpip\udp\UDP_SRV.C

UDP Client: C:\DCRABBIT_10.72\Samples cpip\udp\Udp_cli.c

A good example for TCP is the Modbus TCP Master and slave libraries which use small packets over TCP/IP. These can be found in the Lib\Rabbit4000\Modbus folder.

On the UDP side of things, the Dynamic C BACnet stack at http://bacrabbit.sourceforge.net/ uses UDP to send small to medium packets over UDP.

These examples don’t use the same socket to send and receive data. Would be good to have an example of a client that sends a string to the server, and the server replies on the same socket (the client waits for the reply).

The key is the call to “tcp_tick(NULL)” after receiving the string from the client.

CLIENT (Rabbit):

/*

  • NETWORK CONFIGURATION
  • Please see the function help (Ctrl-H) on TCPCONFIG for instructions on
  • compile-time network configuration.
    */
    #define TCPCONFIG 5

/*

  • Define the number of socket buffers that will be allocated for
  • UDP sockets. We only need one UDP socket, so one socket buffer
  • will be enough.
    */
    #define MAX_UDP_SOCKET_BUFFERS 3

/*

  • UDP demo configuration
    */

/* what local UDP port to use - we receive packets only sent to this port */
#define LOCAL_PORT 10001

/*

  • If REMOTE_IP is set to -1, we will accept packets from anybody.
  • If it is set to 0, we will accept packets from anybody, but
  • the first host to connect to us will complete the socket with
  • their IP address and port number. At that point, the local socket
  • will be limited to that host only.
  • If it is set to an IP address, the socket will only accept packets
  • from that IP.

*/
#define REMOTE_IP -1 // accept packets from all hosts
//#define REMOTE_IP 0 // accept packets from first host
//#define REMOTE_IP IPADDR(192,168,2,71) // accept from this addr only

/********************************

  • End of configuration section *
    ********************************/

#memmap xmem
#use “dcrtcp.lib”

udp_Socket sock;

/* receive one packet (heartbeat) */
int receive_packet(void)
{
static char buf[128];
int len;
longword remoteIP;
word remotePort;
udp_Socket remoteSock;

#GLOBAL_INIT
{
	memset(buf, 0, sizeof(buf));
}

// receive the packet

//len = udp_recv(&sock, buf, sizeof(buf));
len = udp_recvfrom(&sock, buf, sizeof(buf), &remoteIP, &remotePort);
if (-1 == len) return 0; // no packet read. return

printf("Received %i bytes -> %s

", len, buf);

tcp_tick(NULL);                                           // *** VERY IMPORTANT ***

len = udp_sendto(&sock, buf, len, remoteIP, remotePort);
printf("Sent back %i bytes to remote %lX, port %u
", len, remoteIP, (int)remotePort);

return 1;

}

void main()
{
// Start network and wait for interface to come up (or error exit).
sock_init_or_exit(1);

if(!udp_open(&sock, LOCAL_PORT, REMOTE_IP, 0, NULL)) {
	printf("udp_open failed!

");
exit(0);
}

/* receive heartbeats */
for( ; ; ) {
	tcp_tick(NULL);
	receive_packet();
}

}

SERVER (PC-SIDE, Visual C++):

static void RunClient(const char* sServerIPAddr)
{
int socket_desc;
struct sockaddr_in server_addr;
char server_message[2000] = { 0 };
int server_struct_length = sizeof(server_addr);

socket_desc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

if (socket_desc < 0) { printf("Error while creating socket
"); return; }

// Set port and IP:
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(10001);
server_addr.sin_addr.s_addr = inet_addr(sServerIPAddr);

// Get input from the user:
std::cout << "Enter message: ";
std::string client_message;
std::getline(std::cin, client_message);

// Send the message to server:
if (sendto(socket_desc, client_message.c_str(), client_message.size(), 0, (struct sockaddr*)&server_addr, server_struct_length) < 0)
{
printf("Unable to send message
");
return;
}

// Receive the server’s response:
if (recvfrom(socket_desc, server_message, sizeof(server_message), 0, (struct sockaddr*)&server_addr, &server_struct_length) < 0)
{
printf("Error while receiving server’s msg
");
return;
}

std::cout << "Server’s response: " << server_message << std::endl;

// Close the socket:
closesocket(socket_desc);
}