PHP里的socket_recv方法解释

以前一直经为PHP里没有低级的socket帧接收函数,看来是没看仔细,不过那些说明也太少了,(更令人气的里在英文版说明里的例子下有一句话:这个程序不能运行,因为没用listen函数,但在中文版里却没了,这个翻译的人也忒不负责了吧)

int socket_recv ( resource socket, string &buf, int len, int flags )

resource socket 是生成的套接字
string &buf 是接收缓冲区
int len 是你打算接收的长度
int flags 是一个标志
0x1 数据应该带外发送,所谓带外数据就是TCP紧急数据
0x2 使有用的数据复制到缓冲区内,但并不从系统缓冲区内删除。
0x4 不要将包路由出去。
以上三项与sock.h文件中定义完全相同
0x8 数据完整记录
0x100 数据完整处理

当socket_read在PHP_BINARY_READ模式时(默认值,但一般用PHP_NORMAL_READ )与socket_recv基本相同

下面是两个测试成的小例子
发送接收方法:
>> CODE

/*    server sock_accept
* client => filename
* server <= filesize(filename)
* client => "OK"
* server <= file_get_contents(filename)
* client => "FIN"
*    server sock_close
*
* 注意:这里用flags为0x2不清缓冲区将接收到所以读到的数据
*/

server.php

>> CODE
<?php
/*    server sock_accept
* client => filename
* server <= filesize(filename)
* client => "OK"
* server <= file_get_contents(filename)
* client => "FIN"
*    server sock_close
*
* Read buffer save all data that it have recived ever.
*/
$flag = 0x2;
error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we‘re getting
* as it comes in. */
ob_implicit_flush();

$address = ‘127.0.0.1‘;
$port = 10000;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() failed: reason: " . socket_strerror($sock) . "\n";
exit;
}

if (($ret = socket_bind($sock, $address, $port)) < 0) {
echo "socket_bind() failed: reason: " . socket_strerror($ret) . "\n";
exit;
}

if (($ret = socket_listen($sock, 5)) < 0) {
echo "socket_listen() failed: reason: " . socket_strerror($ret) . "\n";
exit;
}

do {
if (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
break;
}else
{
echo "accept \r\n";
}

do {
$p = 0;
if (($ret = socket_recv($msgsock, $buf, 1024, $flag)) ==0 ) {
echo "$buf socket_read() failed reason: " . socket_strerror($ret) . "\n";
break;    // 2;
}
$msg = substr($buf,$p); $p += strlen($msg);
echo "R:$msg\n";

if(file_exists($msg))
{
$fcon = file_get_contents($msg);
$flen = filesize($msg);
if ( ( $ret = socket_write($msgsock,$flen,strlen($flen))) != strlen($flen))
{
echo "Write Error $ret\n";
break;    // 2;
}
echo "S:$flen\n";
if (($ret = socket_recv($msgsock, $buf, 1024, $flag)) ==0 ) {
echo "$buf socket_read() failed reason: " . socket_strerror($ret) . "\n";
break;    // 2;
}
$msg = substr($buf,$p); $p += strlen($msg);
echo "R:$msg\n";
$sndlen = 0;
do
{
$sndlen += socket_write($msgsock,$fcon,$flen-$sndlen);
echo "------[".$sndlen."][$flen]\n";
}while($sndlen<$flen);
echo "S:!!!!!\n";

do
{
socket_recv($msgsock,$buf,1024,$flag);
if(substr($buf,-3) == "FIN")
{
echo "FIN\n";
break 2;
}
}while(true);
}else
{
socket_write($msgsock,"NOFO",4);
echo "File not found\n";
break;
}
} while (true);
socket_close($msgsock);
} while (true);

socket_close($sock);
?>

client.php

>> CODE
<?php
//error_reporting(E_ALL);
$flag = 0x2;
echo "TCP/IP Connection: ";

/* Get the port for the WWW service. */
$service_port = 10000;    //getservbyname(‘www‘, ‘tcp‘);

/* Get the IP address for the target host. */
$address = ‘127.0.0.1‘;    //gethostbyname(‘www.example.com‘);

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
exit;
} else {
echo "OK.\n";
}

echo "Attempting to connect to ‘$address‘ on port ‘$service_port‘...";
$result = socket_connect($socket, $address, $service_port);
if ($result < 0) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
exit;
} else {
echo "OK.\n";
}

$in = "server.php";
echo "S:getfile $in.";
if(socket_write($socket, $in, strlen($in))==0)
{
echo " Err\n";
return;
}
echo " OK\n";

if(($ret = socket_recv($socket,$out, 2048,$flag)) == 0) {
echo "Error read[".$out."]\n";
}
echo "<=:$out\n";
if($out !== "NOFO")
{
echo "=>:OK...";
if(socket_write($socket,"OK",2)==0 )
{
echo " Err\n";
return;
}
echo " OK\n";

$len = strlen($out)+ $out;
$l = 0;
while($len > $l)
{

socket_recv($socket,$t,$len,$flag);
$l= strlen($t);
echo "----[$l][$len]\n";
}
echo "<====:\n[".substr($t,strlen($out))."]\n";

echo "=>:OK...";
if(socket_write($socket,"FIN",3)==0 )
{
echo " Err\n";
return;
}
echo " OK\n";
}else
{
echo "FILE not FOUND on SERVER\n";
}
//socket_close($socket);
sleep(2);
echo "OK.\n\n";
?>
时间: 2024-10-29 10:46:26

PHP里的socket_recv方法解释的相关文章

java 里面的 native 方法

第一篇: 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 一. 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C.这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数.   

WebView组件学习以及WebViewClient 的方法解释

在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件.利用WebView组件就可以做出款完全属于自己的手机浏览器,就想在windows上用IE内核做一个浏览器一样! 1.因为是浏览器,访问网络是必须的.所以,AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错误. 2.设置浏览器是否运行网页上的javascript代码:

Collections里面的binarySearch方法

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.ios培训..Net培训</a>.期待与您交流!------ Collections里面的binarySearch方法查阅API发现其返回值类型为:如果搜索键包含在列表中,则返回搜索键的索引:否则返回 (-(插入点) - 1).插入点 被定义为将键插入列表的那一点:即第一个大于此键的元素索引:如果列表中

自定义InputStream里的read()方法

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.ios培训..Net培训</a>.期待与您交流!------通过对IO的学习,我们知道InputStream里面有一个非常使用的方法:read()方法通过学习发现其底层用到了数组,那么思考到自己定义一个myRead()来达到同样的效果.代码如下: import java.io.*;public clas

Android Service生命周期 Service里面的onStartCommand()方法详解

2014-10-21 23:40 32人阅读 评论(0) 收藏 举报 在Demo上,Start一个Service之后,执行顺序:onCreate - > onStartCommand 然后关闭应用,会重新执行上面两步. 但是把代码拷贝到游戏工程发现,关闭游戏后,只执行了onStart,却没有执行onStartCommand! 查找到下面的文章: [plain] view plaincopy Service里面的onStartCommand()方法详解 启动service的时候,onCreate方

我错误的去试图用QList里面的at方法改变const常量的值

在做曲线工厂的程序的时候,我写了一行代码是这样的: AllLines.at(cruveSecions).p1().setY(20); AllLines是QList<QLineF>类型的,cruveSections是int类型的,这里我犯了一个很低级但是很容易犯的错误,我本是图个方便,然后导致AllLines里面的数据老是更新不了,我很纳闷,最后同事通过查API给我找出了错误的原因.是这样的QList里面通过at访问出来的是个常量,里面的值不能修改成功,但是我很纳闷编译器也不报错,我想可能是se

Angularjs $scope 里面的$apply 方法 和 $watch 方法

Angularjs $scope 里面的$apply 方法 和 $watch 方法 学习要点:1. Angularjs $scope 里面的$apply 方法2. Angularjs $scope 里面的$watch 方法 1. Angularjs $scope 里面的$apply 方法$apply 方法作用:Scope 提供$apply 方法传播 Model 的变化$apply 方法使用情景:AngularJS 外部的控制器( DOM 事件.外部的回调函数如 jQuery UI 空间等)调用了

如何在present出来的viewController里使用push方法

MenuViewController * menuViewController = [[MenuViewController alloc] init]; menuViewController.delegate = self; UIViewController * controller = self.view.window.rootViewController; controller.modalPresentationStyle = UIModalPresentationCurrentContex

进行同一Controller里的不同方法Get请求时,总是定位到Controller里的同一个方法的解决

环境:我用的是webapi+EF4.0+html搭建的环境 问题:进行同一Controller里的不同方法Get请求时,总是定位到Controller里的同一个方法,具体如下: 1.Controller里有如下两个方法: [HttpGet]        public HttpResponseMessage AddPersonToPersonInfo(string pno, string pname); [HttpGet]        public HttpResponseMessage Mo