socket_write:如何在不关闭连接的情况下发送多个数据包?

3

我有这段代码:

$requestCount = 0;
$maxRequestCount = 10;

$ip = "192.168.0.100";
$port = 10000;

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connect = socket_connect($socket, $ip, $port);

while(true){
    if($requestCount == $maxRequestCount){break;}

    $write = socket_write($socket, $getHTTP, strlen($getHTTP));
    echo "Sending TCP message... OK (lenght = $write).<br>";

    $out = '';
    while($out = socket_read($socket, 65536)){echo "Reading response... OK (lenght = ". strlen($out).")<br>";}

    echo "<br>";

    usleep(100);
    $requestCount++;
}

socket_close($socket);

当第一个请求被发出时,连接已经关闭(FIN,ACK)。

我该如何发送10个数据包,然后再关闭连接?

enter image description here


你的 PHP 代码看起来不错。问:另一个主机(服务器?)什么时候关闭它的连接? - FoggyDay
我不明白。你想知道是谁先关闭了连接? - Rodrigo Vieira
3个回答

3
你无法做到。 就像现实中的对话一样,没有办法强迫不感兴趣的人继续听。同样地,你无法阻止另一端计算机关闭套接字。
从你代码中的变量名称来看,似乎你正在发送HTTP请求(只是在不同的端口上)。 HTTP服务器可以选择在响应该连接中收到的第一个请求后关闭连接。这就是这里发生的事情。你需要创建一个新的套接字并重新连接以发送每个请求。
另一个注意点:TCP没有“数据包”。它是面向流的连接。我知道这听起来像是一个小差异,但问如何“在不关闭连接的情况下发送多个数据包”是没有意义的,因为你无法控制TCP如何发送你的消息。

他不想在连接关闭后发送数据包,他希望连接不要关闭,我猜测连接之所以关闭是因为他没有正确地发送数据。如果这是一个HTTP请求,那么他可以发送正确的头部(connection: keep-alive),并且在不关闭套接字的情况下发送请求... - mathieu
没错,你可以在请求中添加一个HTTP头来要求这个,但服务器并不一定会遵守。 - brenns10

1
从数据包捕获可以看出,您向对等方发送了342字节(第4行),然后对等方回复了1446字节(第6行),之后关闭了连接(第7行中的FIN)。从那时起,服务器将不再接受来自客户端的更多数据,因此任何尝试发送更多数据的尝试都将被RST拒绝。
我不知道您想要实现什么,但由于服务器在客户端完成发送数据之前关闭了连接,所以可能存在某些错误。您可以从服务器响应中获取更多详细信息,或者可能只是协议验证,即客户端与服务器不使用相同的协议或不正确地使用协议。例如,如果您尝试使用代码与HTTP服务器通信,则会出现错误,因为您不关心keep-alive,body length等。

根据服务器的情况,我需要为每个答案创建一个新连接吗?你不能强制保持连接吗? - Rodrigo Vieira
1
我猜你正在尝试进行HTTP请求。如果你真的想自己实现而不是使用现有的库,比如curl,请查看标准了解协议的工作原理。即使是基础知识,在这里解释也会太过宽泛。 - Steffen Ullrich

0

可能是远程端关闭了连接。 可能是因为您需要控制socket_write的返回值。您无法保证socket_write会一次性写入整个缓冲区。如果socket_write返回8142(例如),则必须截断缓冲区$getHTTP = substr($getHTTP, 8142);并再次尝试socket_write。如果socket_write(...) === false,则存在错误并且连接已关闭,您也需要进行测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接