gpt4 book ai didi

c - 转发代理检测FIN包

转载 作者:太空宇宙 更新时间:2023-11-04 11:30:02 26 4
gpt4 key购买 nike

我写了一个正向代理。我要把它用于 windows 和 linux。我确实需要根据操作系统进行更改。但是,我不断看到一些提高条件。大多数情况下,我认为它们是由于我在猜测哪个是最后一个数据包(FIN 信号)时产生了误解。目前我确实选择了一组套接字。无论哪个套接字收到信号,我都会对其执行 read() 操作。如果 read 返回 0 那么我假设它是一个 FIN 数据包并且我关闭那个套接字。我的 read() 会不会给出非零值。但是那个数据包确实包含 FIN(我认为它可能发生)。所以,我不会关闭一些套接字,尽管它们已经关闭了。我不确定代理如何检测哪个套接字已关闭?或者哪个是已建立连接上的最后一个数据包。

我的代码如下:

我从客户那里接受了 100 个 fds。我将它们存储在数组 sock_array[total_size] 中。

select(copy_of_sock_array,timeout)                                                          
for(int cnt=0;cnt<total_size;cnt++)
{
if(FD_ISSET(sock_array[cnt],sock_array))
{
ret = recv(sock_array[cnt],buffer,len);
if(ret<=0){
/*This must be a FIN packet */
/* Close corresponding socket which is opened with outer world */
close(/*corresponding socket*/);
}
}
}

这看起来不错吗?

谢谢

最佳答案

您需要进行非阻塞读取,并继续从套接字读取,直到您获得指示您应该停止读取的返回值。

ssize_t r = 0;
for (;;) {
r = recv(sock, buf, bufsz, MSG_DONTWAIT);
if (r <= 0) {
if (r < 0 && errno == EINTR) {
continue;
}
break;
}
/* ... handle data in buf .. */
}
if (r < 0) {
if (errno == EAGAIN) {
/* ... wait in select again ... */
} else {
/* ... handle error ... */
}
} else {
/* got FIN */
}

请注意,收到 FIN 并不一定意味着应该关闭连接。 FIN 只是表示不再发送数据,但对等方可能仍愿意接受更多数据。这可能发生在 HTTP 中,其中客户端只需要一个响应,因此它会在请求后传递一个 FIN。尽管如此,它仍然希望收到响应。

您的代理可能有两个套接字,比如 sock1 和 sock2。因此,在 sock1 上接收到 FIN 应该意味着在发送了已在其上排队的任何数据后,将此指示转发到 sock2(并且镜像也是如此)。您可以使用 shutdown 转发 FIN。

shutdown(sock2, SHUT_WR);

当从 sock1 和 sock2 都收到 FIN 时,您可以在两个套接字上调用 close

所以解决你的问题。

Can it happen that my read() gives non zero value. But that packet does contain FIN (I think it can happen).

是的,这可能会发生。这就是为什么您会继续阅读直到收到停止指示的原因。好吧,从技术上讲,您不必这样做。如果你有每个连接的公平性问题,你可以推迟它,直到你处理了一些其他连接。但是,在进入选择等待之前,您需要返回并完成阅读。

So, I do not close some sockets though they have got closed. I am not sure how proxies detect which socket has closed? Or which is a last packet on the established connection.

正如我所描述的,作为一个(透明的)代理,一旦您在其上转发了 FIN 并在其上收到了 FIN,就可以安全地关闭套接字。如果您不是透明代理,那么您将遵循一套不同的规则,因为在这种情况下您实际上是客户端的服务器。因此,只要您正在实现的应用程序协议(protocol)允许您这样做,您就可以关闭套接字。

关于c - 转发代理检测FIN包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11909543/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com