PHP中的socket编程实践

Posted 问码课堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP中的socket编程实践相关的知识,希望对你有一定的参考价值。

什么是socket?

        网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

        建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

什么是TCP/IP、UDP?

        TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
         UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。
        这里有一张图,表明了这些协议的关系。

socket通讯步骤

PHP相关的socket函数

socket_accept()  # 接受一个Socket连接

socket_clear_error()  # 清除socket的错误或者最后的错误代码

socket_close()  # 关闭一个socket资源

socket_connect()  # 开始一个socket连接

socket_create_listen()  # 在指定端口打开一个socket监听

socket_create_pair()  # 产生一对没有区别的socket到一个数组里

socket_create()  # 产生一个socket,相当于产生一个socket的数据结构socket_get_option()  # 获取socket选项

socket_iovec_add()  # 添加一个新的向量到一个分散/聚合的数组

socket_iovec_alloc()  # 这个函数创建一个能够发送接收读写的iovec数据结构

socket_iovec_delete()  # 删除一个已经分配的iovec

socket_iovec_fetch()  # 返回指定的iovec资源的数据

socket_iovec_free()  # 释放一个iovec资源

socket_iovec_set()  # 设置iovec的数据新值

socket_last_error()  # 获取当前socket的最后错误代码

socket_listen()  # 监听由指定socket的所有连接

socket_read()  # 读取指定长度的数据

socket_readv()  # 读取从分散/聚合数组过来的数据

socket_recv()  # 从socket里结束数据到缓存

socket_recvfrom()  # 接受数据从指定的socket,如果没有指定则默认当socket

socket_recvmsg()  # 从iovec里接受消息

socket_select()  # 多路选择

socket_send()  # 这个函数发送数据到已连接的socket

socket_sendmsg()  # 发送消息到socket

socket_set_block()  # 在socket里设置为块模式

socket_set_nonblock()  # socket里设置为非块模式

socket_set_option()  # 设置socket选项

socket_shutdown()  # 这个函数允许你关闭读、写、或者指定的socket

socket_strerror()  # 返回指定错误号的详细错误

socket_write()  # 写数据到socket缓存

socket_writev()  # 写数据到分散/聚合数组

创建socket关键参数

socket_create($net参数1,$stream参数2,$protocol参数3)

        产生一个Socket,你需要三个参数:一个协议、一个socket类型和一个公共协议类型。产生一个socket有三种协议供选择,继续看下面的内容来获取详细的协议内容。

    1.协议

        AF_INET:IPv4 网络协议。TCP 和 UDP 都可使用此协议。

        AF_INET6:IPv6 网络协议。TCP 和 UDP 都可使用此协议。

        AF_UNIX: 本地通讯协议。具有高性能和低成本的 IPC(进程间通讯)。

    2.Socket类型

       SOCK_STREAM     # TCP 协议套接字。

        SOCK_DGRAM      # UDP协议套接字。 

        SOCK_SEQPACKET 

        SOCK_RAW  

        SOCK_RDM。

    3.公共协议

        SOL_TCP      # TCP 协议。

        SOL_UDP      # UDP协议。

示例代码:

<?php
set_time_limit(0);
$ip = '127.0.0.1';
$port = 8080;
$str_error = '';
//创建一个socket套接字
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//PHP_EOLphp的换行预定义常量
if ($socket == false)
   echo '创建socket套接字失败,原因:' . socket_strerror($socket) . PHP_EOL;

//绑定socket到指定的IP和端口上
if ($str_error = socket_bind($socket, $ip, $port) == false)
   echo '绑定socket端口失败,原因:' . socket_strerror($str_error) . PHP_EOL;

//监听套件字流
if ($str_error = socket_listen($socket, 4) == false)
   echo '绑定socket端口失败,原因:' . socket_strerror($str_error) . PHP_EOL;
//循环监听客户端请求过来的数据
do {
   //获取数据
   $resp_data = socket_accept($socket);
   if ($resp_data) {
       //读取客户端传过来的数据
       $data_str = socket_read($resp_data, 1024);
       if ($data_str) {
           //socket_accept的套接流写入信息,也就是回馈信息给socket_bind()
           //所绑定的主机客户端
           $return_msg = '服务器接受信息 :' . $data_str . PHP_EOL;
           socket_write($resp_data, $return_msg, strlen($return_msg));
       } else {
           echo 'socket_read is fail';
       }
       //关闭套接字流
       socket_close($resp_data);
   }
} while (true);
socket_close($socket);

然后打开cmd运行:php    文件所在目录\socket_server.php

运行成功后不会有提示,接下来再看客户端代码。

<?php
$ip = '127.0.0.1';
$port = 8080;
//创建套接字流
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$socket)
echo "socket_create() failed: reason: " . socket_strerror($socket) . PHP_EOL;
echo "正在连接 {$ip}:{$port}...\n";
$result = socket_connect($socket, $ip, $port);
if (!$result) {
   echo "socket_connect() failed.\nReason: " . socket_strerror($result) . PHP_EOL;
} else {
   echo "连接成功!\n正在发送。。。\n";
   
$message = '这是发送的内容!';
   
//向服务端写入字符串信息
   
if (socket_write($socket, $message, strlen($message)) == false) {
       echo 'fail to write' . socket_strerror(socket_last_error());
   
} else {
       echo '发送成功!' . PHP_EOL;
       
//读取服务端返回来的套接流信息
       
while ($callback = socket_read($socket, 1024)) {
           echo '服务器返回信息:' . PHP_EOL . $callback;
       
}
   }
}
socket_close($socket);

然后可以通过cmd访问:php 文件所在目录\socket_client.php,运行结果:


以上是关于PHP中的socket编程实践的主要内容,如果未能解决你的问题,请参考以下文章

Socket编程实践 --Socket编程导引

PHP编程语言中的socket是啥东西

PHP Socket编程 之 php cc攻击代码与防范方法

php socket编程入门

PHP实现系统编程 --- 网络Socket及IO多路复用网摘

Socket编程实践 --Socket API