Sure, here's the code.
The idea is a client connects via TCP, on port 8585, and sends up to 4 ports on which it wishes to receive UDP packets. The server collects these 4 ports, and then sends back a UDP datagram (just containing in int) to the IP address from where the TCP connection originated.
It's failing at the sendTo() line.
Many thanks.
Code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
/*
* This function reports the error and
* exits back to the shell :
*/
static void
bail(const char *on_what) {
if ( errno != 0 ) {
fputs(strerror(errno),stderr);
fputs(": ",stderr);
}
fputs(on_what,stderr);
fputc('\n',stderr);
exit(1);
}
int main(int argc,char **argv) {
int z, i;
char *srvr_addr = NULL;
char *srvr_port = "8585";
struct sockaddr_in adr_srvr;/* AF_INET */
struct sockaddr_in adr_clnt;/* AF_INET */
struct sockaddr_in adr_udp;
int len_inet; /* length */
int s; /* Socket */
int c; /* Client socket */
int u;
int handshake; /* What we expect from clients */
int ping = 5026;
struct sockaddr_in adr_inet; /* AF_INET */
len_inet = sizeof adr_inet;
/*
* Use a server address from the command
* line, if one has been provided.
* Otherwise, this program will default
* to using the arbitrary address
* 127.0.0.1 :
*/
if ( argc >= 2 ) {
/* Addr on cmdline: */
srvr_addr = argv[1];
} else {
/* Use default address: */
srvr_addr = "127.0.0.1";
}
/*
* If there is a second argument on the
* command line, use it as the port # :
*/
if ( argc >= 3 )
srvr_port = argv[2];
/*
* Create a TDP/IP socket to use :
*/
s = socket(PF_INET,SOCK_STREAM,0);
if ( s == -1 )
bail("socket()");
/*
* Create a server socket address:
*/
memset(&adr_srvr,0,sizeof adr_srvr);
adr_srvr.sin_family = AF_INET;
adr_srvr.sin_port = htons(atoi(srvr_port));
if ( strcmp(srvr_addr,"*") != 0 ) {
/* Normal Address */
adr_srvr.sin_addr.s_addr =
inet_addr(srvr_addr);
if ( adr_srvr.sin_addr.s_addr
== INADDR_NONE )
bail("bad address.");
} else {
/* Wild Address */
adr_srvr.sin_addr.s_addr =
INADDR_ANY;
}
/*
* Bind the server address:
*/
len_inet = sizeof adr_srvr;
z = bind(s,(struct sockaddr *)&adr_srvr,
len_inet);
if ( z == -1 )
bail("bind(2)");
/*
* Make it a listening socket:
*/
z = listen(s,10);
if ( z == -1 )
bail("listen(2)");
/* setup the UDP socket ready and bind it to 8585 */
u = socket(AF_INET,SOCK_DGRAM,0);
if ( u == -1 ) {
bail("UDP socket() call failed to create");
} else {
printf("UDP socket created ping is %d \n", ping);
}
z = bind(u, (struct sockaddr *)&adr_srvr, len_inet);
if ( z == -1) {
bail ("UDP Bind socket bind()");
} else {
printf("UDP socket bound to port \n");
}
/*
* Start the server loop :
*/
for (;;) {
/*
* Wait for a connect :
*/
len_inet = sizeof adr_clnt;
c = accept(s,
(struct sockaddr *)&adr_clnt,
&len_inet);
if ( c == -1 )
bail("accept(2)");
/* Get the peer IP address */
z = getpeername(c, (struct sockaddr *)&adr_clnt, &len_inet);
// IP of peer is now in "adr_inet.sin_addr"
if ( z == -1 ) bail("Failed to get IP address of peer");
printf("Got request from IP address : %s\n", inet_ntoa(adr_clnt.sin_addr));
i = 0;
/* Read the handshake (port) ints and send back, max 4 */
while ( ((z = read(c,&handshake,sizeof(int))) != 0) && (i <=4) ) {
i++;
printf("Client request number %d is for port : %d\n", i, handshake);
/* Send a UDP packet to the requested port */
// Setup our header info for the UDP ping
memset(&adr_udp,0,sizeof adr_udp);
adr_udp.sin_family = AF_INET;
adr_udp.sin_port = htons(handshake);
// UDP packets get sent back to where the TCP request came from
adr_udp.sin_addr.s_addr = adr_clnt.sin_addr.s_addr;
if ( adr_udp.sin_addr.s_addr == INADDR_NONE ) {
bail("bad address.");
}
len_inet = sizeof adr_udp;
// Established a socket, let's send the PING
z = sendto(u, /* Socket to send result */
&ping, /* The datagram result to snd */
sizeof ping, /* The datagram lngth */
0, /* Flags: no options */
(struct sockaddr *)&adr_udp,/* addr */
len_inet); /* Server address length */
if ( z < 0 ) {
bail("Failed to send UDP");
}
}
/*
* Close this client's connection:
*/
close(c);
}
/* Control never gets here */
return 0;
}