PHP中的socket_read和socket_recv区别详解
前几天用PHP写一个socket网络服务,在文档里看到socket_read和socket_recv这两个方法时有点晕,乍一看这不是一样的嘛,干吗还要给两个不同的用法呢。看文档没看太明白,看了下源码才搞清楚,在这里记录一下。
先看一下这两个函数的声明:
stringsocket_read(resource$socket,int$length[,int$type=PHP_BINARY_READ]) intsocket_recv(resource$socket,string&$buf,int$len,int$flags)
可以看到,从声明可以看到,一个是把收到的数据通过执行结果返回,另一个是把收到的数据通过引用的形式返回。另一个区别就是,socket_read多了一个type,socket_recv多了一个flags(够混乱的)。我们先来看看socket_recv的源码吧!
PHP_FUNCTION(socket_recv) { zval *php_sock_res,*buf; char *recv_buf; php_socket *php_sock; int retval; long len,flags;
if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"rzll",&php_sock_res,&buf,&len,&flags)==FAILURE){ return; }
ZEND_FETCH_RESOURCE(php_sock,php_socket*,&php_sock_res,-1,le_socket_name,le_socket);
/*overflowcheck*/ if((len+1)<2){ RETURN_FALSE; }
recv_buf=emalloc(len+1); memset(recv_buf,0,len+1);
if((retval=recv(php_sock->bsd_socket,recv_buf,len,flags))<1){ efree(recv_buf);
zval_dtor(buf); Z_TYPE_P(buf)=IS_NULL; }else{ recv_buf[retval]='\0';
/*Rebuildbufferzval*/ zval_dtor(buf);
Z_STRVAL_P(buf)=recv_buf; Z_STRLEN_P(buf)=retval; Z_TYPE_P(buf)=IS_STRING; }
if(retval==-1){ PHP_SOCKET_ERROR(php_sock,"unabletoreadfromsocket",errno); RETURN_FALSE; }
RETURN_LONG(retval); }