0
votes

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!

2
which system linux or Windows ?lsalamon
How is the client doing its work? Is it multihomed? How does it process the datagram - recv(), recvfrom()? Does it use connect() - yes you can use it on UDP.Duck
A sendto - i've tested this part (the server receives the request). No connect is usedpaquetp
I accept that you know the server works and the datagram goes out and there are no firewall issues, etc. My suspicions are with the client and how it is processing its end.Duck
Thanks Duck - I think I found the culprit - sendto is returning 1 - when I'm trying to send 10512 bytes...setsockopt maybe? Works when I compile the same server on windows, bypassing command handler (default SO_SNDBUF bigger on winsock than vxworks?)...hmmmm...paquetp

2 Answers

1
votes

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

1
votes

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.