socket_read() - socket通信函数
socket_read()
(PHP 4 >= 4.1.0, PHP 5, PHP 7)
Reads a maximum of length bytes from a socket
说明
socket_read(resource $socket,int $length[,int $type= PHP_BINARY_READ]): stringThe function socket_read() reads from the socket resource$socketcreated by the socket_create() or socket_accept() functions.
参数
$socketA valid socket resource created with socket_create() or socket_accept().
$length The maximum number of bytes read is specified by the$lengthparameter. Otherwise you can use r
,n
, or 0
to end reading(depending on the$typeparameter, see below).
Optional$typeparameter is a named constant:
PHP_BINARY_READ
(Default)- use the systemrecv()function. Safe for reading binary data.PHP_NORMAL_READ
- reading stops atnorr.
返回值
socket_read() returns the data as a string on success, or FALSE
on error(including if the remote host has closed the connection). The error code can be retrieved with socket_last_error(). This code may be passed to socket_strerror() to get a textual representation of the error.
socket_read() returns a zero length string("")when there is no more data to read.
参见
socket_accept()
Accepts a connection on a socketsocket_bind()
给套接字绑定名字socket_connect()
开启一个套接字连接socket_listen()
Listens for a connection on a socketsocket_last_error()
Returns the last error on the socketsocket_strerror()
Return a string describing a socket errorsocket_write()
Write to a socket
quote: "Note: socket_read() returns a zero length string ("") when there is no more data to read." This is not true! In a while loop (example case few bytes to receive - just enough for 1 call, but you use a loop to be sure you received all data) if you use you will get: 1st call in loop: data 2nd call in loop: a block forever, if there isnt data anymore or w/e happen to the "other side" So ofc you want to use and you will get: 1st call in loop: data 2nd call in loop: socket_read() returns FALSE (bool) and socket_last_error() gives you a SOCKET_EWOULDBLOCK (http://de1.php.net/manual/de/sockets.constants.php) There is not a single time i got a empty string back from socket_read. And im "working" on this problem(bug?) since a week or so. You better use socket_recv() instead. (good luck)
PHP_NORMAL_READ - reading stops at \n or \r. This seems to be meant literally. If there is a \r, then it will stop reading, even if there is a \n right after it. You have to call the read again just to get rid of the \n.
It is not obvious from the docs or notes... PHP_NORMAL_MODE is different to PHP_BINARY in that the former blocks regardless of socket_set_nonblock, the latter respects block and nonblock.
if you'd like to make a "socket_read" on a linux-system connected with a flash-client (v. 6.0 r81) you have to send a string to the connected port:
PHP 5.2.0 / Win32 / Apache 1.3 - It seems like... PHP_BINARY_READ - works, but returns '', not FALSE... - is blocking, until data received or connection closed - does pass-through \r\n etc. - returns data on data, '' on connection closed - you can detect closed connection by checking for '' (not FALSE as stated i manual) PHP_NORMAL_READ - not working so good... - is non-blocking - does not pass-through \r\n etc. - returns false on no-data, false on connection closed :( - (no way here to detect a closed connection...?) - (is this a bug? http://bugs.php.net/bug.php?id=21880 ) - (is this a bug? http://bugs.php.net/bug.php?id=21197 ) - (could not get data from this option at all in fact...) PHP_BINARY_READ seems to be the "right way to go" for now. Both checking for '' and false to detect closed connection is probably smart, as this "bug"(?) may be fixed...
Binary read is the correct way to read data in most cases, whereas "normal read", is a strange and lazy PHP built mode, that works mostly with terminal data. If you want to keep track of closed connections with binary read, the correct way is NOT to switch from binary to "normal", like some suggests. The correct way is to create some test scenarios and see how PHP deals with specific circumstances. Here is what a quick test shows, when working with non-blocking sockets. There are more errors to consider, but this will get you started.
It seems like in socket_* functions in BLOCKING mode where is no way to check if more than $length bytes are still available in socket (like stream_get_meta_data()['unread_bytes']). So you need to choose your prefered maximum $length (like 133693415:) or use non-blocking mode (for realy big data reciving).
I don't know if is it stated anywhere with this clearance, but here is the source code for detecting the connection abort/closure for sockets testing with socket_read function: ($buf === '') is the key :) I was making an ecrypted tunnel script with mcrypt and was annoying that i could not detect the connection abort from any side.
On non-blocking connections it may not return full length requested.
Another way to bypass the annoying thing with telnet, that send each character as a string ,is to check if the response is "\r\n", that is the string that telnet sends when the user presses enter. Here is an example: