前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >玩转 PHP 网络编程全套之数据接收与发送

玩转 PHP 网络编程全套之数据接收与发送

作者头像
桶哥
发布2020-05-13 09:52:17
1.2K0
发布2020-05-13 09:52:17
举报
文章被收录于专栏:PHP饭米粒PHP饭米粒

TCP/IP协议简单扯蛋

它是一个复杂的协议族,但是经过层层封装之后转换为网络数据帧经过网卡发送出去的,当然在发送之前会先发起一次ARP请求查询一下对方的mac物理地址,对方响应后返回以便封装数据传送,一般来说网卡的mac地址有的是写入EEPROM寄存器里存储起来的。 但是它底层网卡驱动要动的事情,那么我们码农只关注一下传输层的TCP/UDP即可,TCP传输层拥有自己的接收与发送缓冲区,而UDP并没有,每次发送数据时,接收端必须立即接受,否则丢包。TCP的发送端与接收端读写次数并不一定相等,这就是字节流的概念,而UDP则是数据报提供不可靠传输。

发送函数API

代码语言:javascript
复制
 socket_write ( resource $socket , string $buffer [, int $length = 0 ] ) : int
 socket_send ( resource $socket , string $buf , int $len , int $flags ) : int
 socket_sendmsg ( resource $socket , array $message [, int $flags = 0 ] ) : int
 socket_sendto( resource $socket , string $buf , int $len , int $flags , string $addr [, int $port = 0 ] ) : int

接收函数API

代码语言:javascript
复制
socket_read ( resource $socket , int $length [, int $type = PHP_BINARY_READ ] ) : string
socket_recv ( resource $socket , string &$buf , int $len , int $flags ) : int
socket_recvfrom( resource $socket , string &$buf , int $len , int $flags, string &$name [, int &$port ] ) : int
socket_recvmsg ( resource $socket , array &$message [, int $flags = 0 ] ) : int

TCP字节流的发送与接收

代码语言:javascript
复制
$ip = "0.0.0.0";
$port = $argv[1];
$sockefd = socket_create(AF_INET,SOCK_STREAM,0);
socket_set_option($sockefd,SOL_SOCKET,SO_REUSEPORT,1);
socket_bind($sockefd,$ip,$port);
socket_listen($sockefd,5);

while (1){

    $connfd = socket_accept($sockefd);
    $message = "php is the best language in the world!";
    $remoteIp;
    $remoteAddr;
    //获取socket 文件描述符绑定的端口和地址
    //网卡接收数据时执行的中断函数会根据端口找到对应的文件描符并写入其缓冲区
    //一般带有缓冲的称为IO流【用户空间】
    socket_getpeername($connfd,$remoteIp,$remoteAddr);
    echo "有客户端连接,ip为:".$remoteIp.",端口为:".$remoteAddr.PHP_EOL;
    if ($connfd){
        socket_send($connfd,$message,strlen($message),0);
        while (1){
            $recvMessage = "";
            $recvBytes = socket_recv($connfd,$recvMessage,8192,0);
            if ($recvBytes){
                $sendBytes = socket_sendto($connfd,$recvMessage,$recvBytes,0,$remoteIp,$remoteAddr);
                fprintf(STDOUT,"发送了%d 字节\n",$sendBytes);
            }
        }
    }

}
socket_close($sockefd);
socket_close($connfd);

UDP数据报的发送与接收

UDP SEVER 端

代码语言:javascript
复制
$ip = "0.0.0.0";
$port = $argv[1];
$sockefd = socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);
socket_set_option($sockefd,SOL_SOCKET,SO_REUSEPORT,1);
socket_bind($sockefd,$ip,$port);
function resetClient()
{
//此结构PHP.net手册并没有细说,而是本人通过调试低层内核代码获取以及参考unix API
//大家可以自行参考
    return  [
        'name' =>[],//socket 套接字地址 【有通用地址和专用地址】 协议不同 此参数内容结构不同,后面扯
        'control' =>[],//
        'iov' => [],//数据 可参考 struct iovec
        'flags'=> 0,//接收消息标志位  给0正常就行
        'controllen'=>8192//辅助数据的地址
    ];
}

while(1){
    $client=resetClient(); 
    //在此阻塞SLEEPING
    socket_recvmsg($sockefd,$client,0);
    print_r($client);
    if (isset($client['name']['addr'])){
        socket_sendto($sockefd,"world",5,0,$client['name']['addr'],$client['name']['port']);
    }

    sleep(2);
}

socket_close($sockefd);

UPD CLIENT端

代码语言:javascript
复制
$ip = "127.0.0.1";
$port = $argv[1];
$socketfd = socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);

$msgStruct = [
    'name' =>[
        'addr'=>$ip,
        'port'=>$port
    ],
    'control' =>[],
    'iov' => ["hello,world"],
    'flags'=> 0
];

while (1){
//阻塞读取终端的输入
    $data = fread(STDIN,8192);
    if ($data){
        $recvMsg="";$remoteIp;$remoteAddr;
        socket_sendto($socketfd,$data,strlen($data),0,$ip,$port);
        socket_recvfrom($socketfd,$recvMsg,8192,0,$remoteIp,$remoteAddr);
        fprintf(STDOUT,"ip:%s,port:%d,msg:%s\n",$remoteIp,$remoteAddr,$recvMsg);
    }
}

socket_close($socketfd);

启动后netstat 观察

大家应该看到比较明显的地方是State它并没有显示什么LISTEN

PS:是每次客户端连接端口是系统随机分配的 UDP通信并不像tcp那样连接的操作,而是大家向socket【绑架了ip和端口的文件描述符】进行读写操作完成了所谓的通信。 它的通信只要指定ip,port和数据即可通信,是面向报文并非连接。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP饭米粒 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TCP/IP协议简单扯蛋
  • 发送函数API
  • 接收函数API
  • TCP字节流的发送与接收
  • UDP数据报的发送与接收
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档