Reputation: 1651
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
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
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