您的位置:首页 > 其它

如何通过socket进行大量返回信息的读取

2010-11-22 19:29 253 查看
我们知道,TCP协议本身一个流的协议,信息之间是没有边界的,均是字节为单位的流,在使用php进行读取socket返回的时候,根据我们的应用场景,可能只需要读取一行返回即可,此时我们非常简单调用如下API即可实现:



$buffer = fgets( $sock );




API说明:

string fgets ( int handle [, int length])


从 handle 指向的文件中读取一行并返回长度最多为 length - 1 字节的字符串。碰到换行符(包括在返回值中)、EOF 或者已经读取了 length - 1 字节后停止(看先碰到那一种情况)。如果没有指定 length,则默认为 1K,或者说 1024 字节。

出错时返回 FALSE



如果在读取的过程中,需要捕捉对应的读取是否超时,则可以调用:

$stream_info  = stream_get_meta_data( $sock );
if ( $stream_info['timed_out'] ) {
    echo  'socket_timed_out';
}




在实际的应用当作,server返回的信息往往不是简单一号,而是一个有格式的大串,百日返回一篇文章,各个段落之间是有换行的,或者返回一个json 串,每个json的字串是有换行符,这种情况下,我们是不能直接用fgets进行读取的,否则只能读取到第一行,其他的内容将会被截断。

我们可以使用另外指定结束符的读取API:

string stream_get_line ( resource handle, int length, string ending)


Returns a string of up to length bytes read from the file pointed to by handle. Reading ends when length bytes have been read, when the string specified by ending is found (which is notincluded in the return value), or on EOF (whichever comes first). If an error occurs, returns FALSE.

通过我们指定自己的ending串,我们就可以读取整段的内容,demo如下:

$str = stream_get_line ($obj_sock->sock, 4096, "/r/n");


但请注意:这里的读取其实每次只返回read buffer读取到的内容而已,对json串的返回,有可能读取一次是无法读取全数据,因此需要进行循环读取。

$stream_info  = stream_get_meta_data( $obj_sock->sock );

 while(isset($stream_info['unread_bytes'])
    && $stream_info['unread_bytes'] > 0){
       $str .= stream_get_line ($obj_sock->sock, 4096, "/r/n");
       $stream_info  = stream_get_meta_data( $obj_sock->sock );
 }


直到读取的unread_btyes=0为止,当然这里的更加严谨的做法应该是加入超时的判断。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐