百科狗-知识改变命运!
--

socket_read() - socket通信函数

梵高12个月前 (11-21)阅读数 8#技术干货
文章标签绑定

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]): string

The function socket_read() reads from the socket resource$socketcreated by the socket_create() or socket_accept() functions.

参数

$socket

A 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).

$type

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.

Note:

socket_read() - socket通信函数

socket_read() returns a zero length string("")when there is no more data to read.

参见

  • socket_accept()Accepts a connection on a socket
  • socket_bind()给套接字绑定名字
  • socket_connect()开启一个套接字连接
  • socket_listen()Listens for a connection on a socket
  • socket_last_error()Returns the last error on the socket
  • socket_strerror()Return a string describing a socket error
  • socket_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:
内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)