tags:

views:

562

answers:

3

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!

+1  A: 

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.

Charlie Martin
I ommitted them for brevity.
paquetp
what were the error codes then? The obvious things that could happen are permissions error, a firewall intercepting random UDP packets, and some kind of I/O error at one end or the other.
Charlie Martin
Everything was fine up to the sendto (no error codes). So you agree I should be able to open a second socket and reply from a different process? I don't need to reply from the same socket I "recvfrom"ed?
paquetp
No you don't. But since any process can blast data back at your client programs often check to see if they are receiving data from where they sent it. Among several possibilities is the one in which your client is simply tossing the data because your server sub-process is using a different port.
Duck
Seriously, read through that tutorial. It's also got the code for what you want to do.
Charlie Martin
@Charlie - perhaps I wasn't clear in my question - I've seen tutorials like this one before, the question is "can I reply from a new socket opened from a different process, or do I have to reply from the one I "recvfrom"'ed. This example doesn't show the reply from the server
paquetp
A: 

Use this tool to capture packets Microsoft Network Monitor 3.2 and verify if origin/destination is correct.

lsalamon
or the more popular open-source Wireshark instead (the network sniffing tool formerly known as Ethereal)
gbjbaanb
A: 

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).

cmeerw
That's what I thought - the reply message's source port has to be the destination port from the original message. Since the application will only be sending, I don't think I'll have a problem with receiving from the wrong process - I'll try to bind the source port before I send and see if that fixes it - if it does, I'll accept this answer.
paquetp
Sorry cmeerw, but it might be awhile before I attempt this
paquetp
I never did try this, and won't because we switched to TCP...so I'll accept this answer as the best
paquetp