PHPCon Poland 2024

socket_shutdown

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

socket_shutdown关闭套接字接收或发送,或两者都关闭

说明

socket_shutdown(Socket $socket, int $mode = 2): bool

socket_shutdown() 函数允许通过 socket 停止接收、发送或所有数据(默认)。

注意:

关联的一个或多个缓冲区可能会清空,也可能不会。

参数

socket

socket_create() 创建的 Socket 实例。

mode

mode 的值可以是以下之一:

mode 可用值
0 关闭套接字读
1 关闭套接字写
2 关闭套接字读和写

返回值

成功时返回 true, 或者在失败时返回 false

更新日志

版本 说明
8.0.0 现在 socketSocket 实例, 之前是 resource
add a note

User Contributed Notes 5 notes

up
4
ludvig dot ericson at gmail dot com
18 years ago
Sockets should be first shutdown and then closed.
<?php
// Sample: Closing sockets gracefully
socket_shutdown($sock, 2);
socket_close($sock);
?>
up
2
Anonymous
1 year ago
Shutting down is a formality two peers can do before closing their connections. It's not required, but it can help assert your I/O procedures, so it's useful.

If writing is shut down, trying to send will result in a pipe error, and the remote peer will read an empty string after receiving all other pending data.

If reading is shut down, trying to receive will return an empty string, and the remote peer will get a pipe error if they try to send.

Writing should be shut down first between two peers. Remaining data should then be read and handled. If anything is sent at this point it should be a "goodbye" (nothing that requires the remote peer to write back to you). Finally, reading can be shut down.

Selection on a shut down channel will always succeed. Similarly, the remote peer will always succeed at selecting the opposite channel.
up
2
renmengyang567 at gmail dot com
5 years ago
<explain>
In this case, the TCP client is gracefully disconnected from the server

<?php

define
('BUF_SIZE',10);

// create for tcp
$sock = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
socket_bind($sock, '127.0.0.1',5200);
socket_listen($sock,1024);
$fp = fopen('./socket_shutdown.php','rb');
$clnt_sock = socket_accept($sock);

while(!
feof($fp)) {
$str = fread($fp,BUF_SIZE);
socket_write($clnt_sock,$str,BUF_SIZE);
}

$eof = "\n";
socket_write($clnt_sock,$eof,strlen($eof));

//disconnect output stream(断开输入流)
socket_shutdown($clnt_sock,1);
$ret = socket_read($clnt_sock, 100);
printf("Message from client:%s\n",$ret);
socket_close($clnt_sock);
socket_close($sock);
?>

<?php
// for tcp-client
$clnt_sock = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
socket_connect($clnt_sock, '127.0.0.1', 5200);
while ((
$cnt= @socket_read($clnt_sock, 10,PHP_NORMAL_READ)) !==false) {
file_put_contents('./receive.data',$cnt,FILE_APPEND);
}
print
"receive file data".PHP_EOL;
socket_write($clnt_sock, "Tank you");
socket_close($clnt_sock);
?>
up
1
richard dot thomas at psysolutions dot com
18 years ago
That is not a good example of a graceful shutdown. One should close the sending side of the socket and continue to read until the remote end closes its sending connection.
up
-2
recycling dot sp dot am at gmail dot com
13 years ago
Shutdown and SOL_TCP:
<?php
$a
= socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_shutdown($a, 2)
?>
PHP Warning: socket_shutdown(): unable to shutdown socket [107]: Transport endpoint is not connected

Shutdown and SOL_UDP:
<?php
$a
= socket_create(AF_INET, SOCK_STREAM, SOL_UDP);
socket_shutdown($a, 2)
?>
PHP Warning: socket_shutdown(): unable to shutdown socket [107]: Transport endpoint is not connected

Conclusion: if you are not actually connected, shutdown will fails with socket_error = 107, Transport endpoint is not connected. This is true for both TPC and UDP connection (which is suprising, UDP being a connectionless protocol). This is true no matter the value set for the how parameter.
To Top