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_EOL为php的换行预定义常量
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编程实践的主要内容,如果未能解决你的问题,请参考以下文章
PHP Socket编程 之 php cc攻击代码与防范方法