paquetp
paquetp

Reputation: 1651

Replying to a client over sockets (UDP) from a different process

I have a server than is a "command handler" process. It receives messages over UDP, and delegates the work to do to a different process by communicating to that process through it's published API (whatever IPC mechanism that process employes). Our system has several cooperating processes. The result of that API call is then then sent back to the client from the command handler process.

One command is to control a data stream that is generated from another process to the client (a "connect" message).

Should this work? I send the IP address and port number of the client to the other process, that process creates a new socket, and does a sendto...I've traced through the code and everything looks good, but the client is still blocked on the receive...I know if I do a sendto from the command handler, it gets the response, but not from the new socket.

Here's some example code:

#define LEN 10000
char buffer[LEN];
int sfd, nsfd, bread, addrsize;
struct sockaddr_in addr;
addrsize = sizeof (struct sockaddr_in);
server.sin_family = AF_INET;
server.sin_port = htons(5200);
server.sin_addr.s_addr = INADDR_ANY;
sfd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bind (sfd, (struct sockaddr*)&server, addrsize);
bread = recvfrom(sfd, buffer, LEN, 0, &addr, &addrsize);

/* send IP address and port number through the API to another process */
/* in that other process, I do something like this...addr has the IP
 * address and port in it from above: */

nsfd = socket (AF_INET, SOCK_DGRAM, IPROTO_UDP);
sendto(nsfd, buff, bread, 0, &addr, sizeof(addr));

SO please help!

Upvotes: 0

Views: 2510

Answers (2)

cmeerw
cmeerw

Reputation: 7356

Your client (or a firewall in between) will likely get confused by receiving the response from a different source port than it sent the request to (as the OS will just pick a random source port for the new socket).

One way around this is to use the SO_REUSEADDR socket option in the server and explicitely bind to the correct port when sending the reply. But that would also have the undesireable side-effect that UDP requests might be redirected to one of the other processes instead of the server.

Another option (if you are using Unix/Linux) is to pass the server socket to the other processes via a unix domain socket (via sendmsg and ancillary data).

Upvotes: 1

Charlie Martin
Charlie Martin

Reputation: 112414

You should be testing for the error return, something like

if((nsfd = socket (AF_INET, SOCK_DGRAM, IPROTO_UDP)) < 0} {
    perror("at socket open");
    // I'd call exit here, probably
}
if(sendto(nsfd, buff, bread, 0, &addr, sizeof(addr) < 0){
    perror("At sendto");
}

There's a nice tutorial example here.

Upvotes: 1

Related Questions