从不同进程通过套接字 (UDP) 回复客户端

发布于 2024-07-17 07:11:19 字数 1085 浏览 5 评论 0原文

我有一个服务器而不是“命令处理程序”进程。 它通过 UDP 接收消息,并通过其发布的 API(无论该进程采用何种 IPC 机制)与该进程进行通信,从而将要做的工作委托给不同的进程。 我们的系统有多个协作进程。 然后,该 API 调用的结果会从命令处理程序进程发送回客户端。

一个命令是控制从另一个进程生成到客户端的数据流(“连接”消息)。

这应该有效吗? 我将客户端的 IP 地址和端口号发送到另一个进程,该进程创建一个新套接字,并执行 sendto...我已经跟踪了代码,一切看起来都很好,但客户端仍然被阻止接收...我知道如果我从命令处理程序执行 sendto,它会收到响应,但不会从新套接字收到响应。

这是一些示例代码:

#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));

所以请帮忙!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

澉约 2024-07-24 07:11:19

您的客户端(或中间的防火墙)可能会因为从与发送请求的源端口不同的源端口接收响应而感到困惑(因为操作系统只会为新套接字选择一个随机源端口)。

解决此问题的一种方法是在服务器中使用 SO_REUSEADDR 套接字选项,并在发送回复时显式绑定到正确的端口。 但这也会产生不良的副作用,即 UDP 请求可能会被重定向到其他进程之一而不是服务器。

另一种选择(如果您使用的是 Unix/Linux)是通过 unix 域套接字(通过 sendmsg 和辅助数据)将服务器套接字传递给其他进程。

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

冬天旳寂寞 2024-07-24 07:11:19

您应该测试错误返回,例如

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");
}

这里有一个很好的教程示例

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文