sockaddr, Sendto with UDP

Hi, I am using UDP protocol in my application but I have been in trouble when use sendto since it is no clear enough how the struct sockaddr should be used (it is a parameter to sendto). If I can find an example about how to stablish communication between two pc`s using socket, sendto and rcv that would be great. Could any one help, please. Thanks a lot.

a simple example how to send data over UDP

#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <netdb.h>

int SendTo (int sock, const char *host, unsigned short int port, const char *buffer, int size)
{
	struct sockaddr_in addr;
	struct hostent *hp;
	int v;

	if ((hp = gethostbyname(host)) == NULL)
		return -1;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
	addr.sin_port = htons(port);

	return sendto(sock, buffer, size, 0, (struct sockaddr *)&addr, sizeof(addr));
}

sock = socket(AF_INET, SOCK_DGRAM, 0);
port = 12345;
SendTo(sock, "172.16.1.1", port, "this is a test", 14);

Sending a message seems to work OK, but I am still having problem when receiving a message I am using:
recvfrom( id_socket, buff, 14, 0, &from,&fromlen );
and get the following error: message too long.
Any hint ? Am I doing “receive” the rigth way? If no, how should I?

the from should be a sockaddr_in structure
also you have to pre-fill fromlen argument to available size each time you call the recvfrom()

struct sockaddr_in from;

fromlen = sizeof(from);
recvfrom( id_socket, buff, 14, 0, (struct sockaddr *)&from,&fromlen );

Now, there is no error, but the process blocks (replay state) at the recvfrom call, so I could not receive anything at all.
Here is the code:
extern int errno;

int EnviarMensUDP( int sock,
const char *host,
unsigned short int puerto,
const char *mens,
int tam_mens )
{
struct sockaddr_in dir;
struct hostent var_hip,
*hip = &var_hip;

if ((hip = gethostbyname(host)) == NULL) return -1;

memset(&dir, 0, sizeof(dir));
dir.sin_family = AF_INET;
memcpy(&dir.sin_addr, hip->h_addr, hip->h_length);
dir.sin_port = htons(puerto);

return sendto(sock, mens, tam_mens, 0, (struct sockaddr *)&dir, sizeof(dir));
}

int main(void){
int id_socket,
pid_padre,
i,
result;
char mens_entrada[13];
unsigned short int puerto;
size_t len_mens_entrada = 13;
struct sockaddr_in from;
socklen_t fromlen;

id_socket = socket(AF_INET, SOCK_DGRAM, 0);
puerto = 2002;
fromlen = sizeof(from);

if ((pid_padre = fork())== -1)return -1;

if (pid_padre){
for(i=0; i < 3; i++){
result = EnviarMensUDP(id_socket, “150.0.56.10”, puerto, “Mens del PADRE”, 13);
printf(“Resultado de envio: %d \n”, result);
sleep(3);
}
}
else {
for (i=0; i < 3; i++){
printf(“No: %d \n”, i);
result = recvfrom( id_socket,
mens_entrada,
13,
0,
(struct sockaddr *)&from,
&fromlen );
printf(“Result: %d – Mens: %s \n”,result, mens_entrada );
fprintf( stderr, “Error: %s\n”, strerror( errno ) );
sleep(3);
}
}
return 0;
}

You do not use bind() to setup the UDP listening port correctly …

This is the complete source code i used to test UDP

After you compile it into executable use: (assuming name of executable is tudp)
tudp - start UDP server on port
tudp - send a test string to the server listening on port

Note: replace TargetHost in source to match your server IP address

#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <netdb.h>


#define TargetHost		"172.16.1.1"
#define BufferSize		256
#define TestBuffer		"this is a test"


int SendTo (int sock, const char *host, unsigned short int port, const char *buffer, int size)
{
	struct sockaddr_in addr;
	struct hostent *hp;
	int v;

	if ((hp = gethostbyname(host)) == NULL)
		return -1;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
	addr.sin_port = htons(port);

	return sendto(sock, buffer, size, 0, (struct sockaddr *)&addr, sizeof(addr));
}


int main (int argc, char *argv [])
{
	unsigned short int port;
	int v, sock, addr_len, size = BufferSize;
	struct sockaddr_in addr;
	char buffer [BufferSize];
	
	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
		return -1;

	port = atoi(argv[1]);
	
	if (argc > 2)
	{
		memset(&addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		addr.sin_addr.s_addr = INADDR_ANY;
		addr.sin_port = htons(port);

		if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
			return -1;

		for (;;)
		{
			addr_len = sizeof(addr);
			
			if ((v = recvfrom(sock, buffer, size, 0, (struct sockaddr *)&addr, &addr_len)) > 0)
			{
				printf("buffer '%s'\n", buffer);
			}
			else
				printf("nothing\n");
		}
	}
	
	SendTo(sock, TargetHost, port, TestBuffer, sizeof(TestBuffer) + 1);

	return 0;
}

Now it is working. Thanks a lot for your help. I think QNX must improve the DOC.

what’s this got to do with QNX? These are standard network programming issues. Perhaps you should consult the Stevens books.

Error Combilation

gcc receive.c -o tudp -Wall

receive.c: In function SendTo': receive.c:21: warning: unused variable v’
/tmp/ccTNpv0C.o: In function SendTo': /tmp/ccTNpv0C.o(.text+0x15): undefined reference to gethostbyname’
/tmp/ccTNpv0C.o(.text+0x97): undefined reference to sendto' /tmp/ccTNpv0C.o: In function main’:
/tmp/ccTNpv0C.o(.text+0xc2): undefined reference to socket' /tmp/ccTNpv0C.o(.text+0x146): undefined reference to bind’
/tmp/ccTNpv0C.o(.text+0x188): undefined reference to `recvfrom’

What problem?
Thanks
Hung

You need to link with the socket library add -l socket to link stage.

Thanks a lot for your help.
Now I want to transmit data (Using UDP Protocol) between two modem, don’t I?. And How to do that?
thanks
Hung

Programatically, there is nothing else to do. You need to set up the TCP/IP link over the modem. The usual way this is done is with PPP, but you didn’t say what type of modem, or give any other details.

Thanks for your reply. I want transmit data between two PCs, which be connected together via MODEM (directly or keyboard ). If this is posible, Could you tell me the details.
I’m using two data fax MODEMs - 56Kbps.
thanks for reading
Hung

If it’s two modem,s one as to be setup as a ppp server and the other one as a ppp client. This is well explained in the documentation.

Thanks for your reply.
But, I have no network, I’m programming to transmit data between two Pcs via MODEM (directly or local switchboard). could tell me the detail

Thanks,
Hung

I think you are confusing Ethernet or DSL with “a Network”. You will start up TCP/IP, and then start PPP as the protocol across the serial/modem connection. This is a network. TCP/IP packets will be transported over the modem, and presto, all those nice utilities, like ftp, and telnet work, although limited in speed.

Hi All,

I tried to use Mezek’s sample code for my app. It seems to work fine when I’m sending a datagram from one machine to another. However now I try to use the same code to try and send a packet from one application to another application within the same machine (local - using 127.0.0.1) and I’m not having any success.

Are there any other variables I need to change for local packet transfer ?

Cheers

in that case you have to modify the code to use different port in each application, eg:

app1:
bind on PORT1
sendto PORT2

app2:
bind on PORT2
sendto PORT1