2015-04-08 103 views
2

我有这样的代码:socket_write:如何发送多个数据包而不关闭连接?

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

当第一请求是由该连接已经关闭(FYN,ACK)。 我如何发送10个数据包,然后连接关闭?

enter image description here

+0

您的PHP代码看起来不错。问:其他主机(服务器?)什么时候关闭它的连接? – FoggyDay

+0

我不明白。你想知道谁先关闭了连接? – Slowaways

回答

1

你不能。就像现实世界的对话一样,没有办法强迫某些不感兴趣的人继续倾听。以同样的方式,您不能阻止套接字另一端的计算机关闭它。

从你的代码中的变量名判断,它看起来像你发送HTTP请求(就在不同的端口上)。 HTTP服务器可以在响应他们在该连接中获得的第一个请求后关闭连接。这似乎是在这里发生的。您将不得不创建一个新套接字并重新连接以发送每个请求。

另一个说明:TCP没有“数据包”。这是一个面向流的连接。我知道这听起来像是一个迂腐的区别,但问你如何“在不关闭连接的情况下发送多个数据包”是没有意义的,因为你无法控制TCP如何发送消息。

+0

在连接关闭后,他不想发送数据包,他希望连接不关闭,我猜连接正在关闭,因为他没有以正确的方式发送数据。 如果这是一个http请求,那么他可以发送正确的头部(连接:保持活动状态)并发送请求而不关闭套接字... – mathieu

+0

确实,您可以添加一个http头来请求该请求,但服务器isn没有义务遵守这一点。 – brenns10

0

大概远端关闭了连接。 可能是因为你必须控制socket_write返回的内容。您不保证socket_write会立即写入您的整个缓冲区。如果socket_write返回8142(例如),则必须剪切缓冲区$getHTTP = substr($getHTTP, 8142);并再次尝试socket_write。如果socket_write(...)=== false有错误并且连接已关闭,则您也必须对其进行测试。

1

从数据包捕获可以看出,你发送342字节到对等体(第4行),然后对等响应1446字节(第6行),然后关闭连接(第7行FIN)。从那时起,服务器将不会接受来自客户端的更多数据,因此任何发送更多数据的尝试都将被RST拒绝。

我不知道你要达到什么目的,但由于服务器在客户端完成发送数据之前关闭了连接,所以可能会出现一些错误。您可能会从服务器响应中获得更多详细信息,或者它可能只是一种协议验证,即客户端不会以与服务器相同的协议或不正确的方式说服协议。例如,如果您尝试使用您的代码与HTTP服务器通话,那么这将会是错误的,因为您不关心保持活着,体长等。

+0

取决于服务器,我需要为每个答案创建一个新的连接?你不能强制保持连接? – Slowaways

+1

我假设你正在尝试执行HTTP请求。如果你真的想自己实现它,而不是像curl那样使用现有的库,请查看[standards](https://www.ietf.org/rfc/rfc2616.txt)协议是如何工作的。这将是广泛的解释这里甚至基本知识。 –

相关问题