Socket编程 之 Socket函数简介

96
实验楼
2017.12.19 11:28 字数 961

说明:文章截选自实验楼教程【PHP Socket编程】,该教程由用户“水煮牛肉”发布在实验楼上,未经允许,禁止转载;

Socket简介

许多第一次接触 Socket 编程的同学并不知道 Socket 是什么意思,就算知道它的翻译 “套接字” 也不明白这到底是个什么东西。其实 Socket 还有一个意思,就是 “插座”,根据这个意思来理解抽象的 “套接字” 会容易得多,创建 Socket 就是装一个插座,为电器提供电能服务,用各种电气标准把它们连接起来

先来一段程序跑起来, 再逐一解释每个函数的使用方法,及参数释义

// server.php
<?php 

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_bind($sock, "127.0.0.1", 80);

socket_listen($sock);

for ( ; ; ) {
    $conn = socket_accept($sock);
    
    $write_buffer = "HTTP/1.0 200 OK\r\nServer: my_server\r\nContent-Type: text/html; charset=utf-8\r\n\r\nhello!world";
    
    socket_write($conn, $write_buffer);
    
    socket_close($conn);
}

运行:

sudo php server.php

因为要使用80端口,必须使用root身份运行,运行成功后,打开浏览器,输入http://127.0.0.1,回车看到结果

Socket函数介绍

socket_create

函数原型: resource socket_create ( int $domain , int $type , int $protocol )

  • domain:AF_INET、AF_INET6、AF_UNIX,AF的释义就 address family,地址族的意思
  • type: SOCK_STREAM、SOCK_DGRAM等,最常用的就是SOCK_STREAM,基于字节流的SOCKET类型,也是TCP协议使用的类型
  • protocol: SOL_TCP、SOL_UDP

socket_bind

函数原型: bool socket_bind ( resource $socket , string $address [, int $port = 0 ] )

  • socket: 使用socket_create创建的socket资源
  • address: ip地址
  • port: 监听的端口号,WEB服务器通常为80端口

socket_listen

函数原型: bool socket_listen ( resource $socket [, int $backlog = 0 ] )

  • socket: 使用socket_create创建的socket资源
  • backlog: 等待处理连接队列的最大长度

stream_socket_server

由于创建一个SOCKET的流程总是 socket、bind、listen,所以PHP提供了一个非常方便的函数一次性创建、绑定端口、监听端口

函数原型: resource stream_socket_server ( string $local_socket [, int &$errno [, string &$errstr [, int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN [, resource $context ]]]] )

  • local_socket: 协议名://地址:端口号
  • errno: 错误码
  • errstr: 错误信息
  • flags: 只使用该函数的部分功能
  • context: 使用stream_context_create函数创建的资源流上下文

有了这个函数之后,上面的代码可以改写成:

// server.php
<?php 

$sock = stream_socket_server("tcp://127.0.0.1:80", $errno, $errstr);

for ( ; ; ) {
    $conn = stream_socket_accept($sock);
    
    $write_buffer = "HTTP/1.0 200 OK\r\nServer: my_server\r\nContent-Type: text/html; charset=utf-8\r\n\r\nhello!world";
    
    fwrite($conn, $write_buffer);
    
    fclose($conn);
}

需要注意的是,这里不能使用socket_accept,因为stream_socket_serversocket_create创建的不是同一种资源,stream_socket_server创建的是stream资源,这也是为什么可以用fwritefreadfclose操作该资源的原因. 而socket_create创建的是socket资源,而不是stream资源,所以socket_create创建的资源只能用socket_writesocket_readsocket_close来操作.

socket_accept

函数原型: resource socket_accept ( resource $socket )

  • socket: 使用socket_create创建的socket资源

stream_socket_accept

函数原型: resource stream_socket_accept ( resource $server_socket [, float $timeout = ini_get("default_socket_timeout") [, string &$peername ]] )

  • server_socket: 使用stream_socket_server创建的stream资源
  • timeout: 超时时间
  • peername: 设置客户端主机名称

socket_write

函数原型: int socket_write ( resource $socket , string $buffer [, int $length ] )

  • socket: 调用socket_accept接受的新连接产生的socket资源
  • buffer: 写入到socket资源中的数据
  • length: 控制写入到socket资源中的buffer的长度,如果长度大于buffer的容量,则取buffer的容量

socket_close

函数原型: void socket_close ( resource $socket )

  • socket: socket_accept或者socket_create产生的资源,不能用于stream资源的关闭

这章我们介绍了一些最常用的socket相关函数,值得注意的是stream_socket_serversocket_create创建的资源不是同一种类型,针对这些资源的函数不能混用

最后

想要学习PHPSocket编程,点击教程【PHP Socket编程】即可,该教程共6个实验:

  • TCP协议介绍
  • Socket编程
  • 多进程编程
  • IO复用
  • 进程间通信及守护进程
    综合练习
PHP
Web note ad 1