PHP socket笔记

socket不好理解……个人理解,以PHP开发作为socket服务器,然后html5的websocket做为客户端,写一个聊天室,暂时只在网上找到聊天室,有空去找找一对一的。

$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);// IPv4 网络协议,创建socket
socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, TRUE);
socket_bind($this->socket, $host, $port);
socket_listen($this->socket, $max);

 

public function start() {
        $ii = 0;
        while(true) {
            $cycle = $this->accept;
            $cycle[] = $this->socket;
            socket_select($cycle, $write, $except, null);//监听各个客户端有没有信息进来,如果没有就卡在这里了。这个是非阻塞阻塞的获取信息,如果是socket_accept的话有客户端异常断开服务器就阻塞了,一般这里只选择出发生了信息交流的套接字。比如构造函数后会有$this->socket,如果没有任何客户端连接,就会停留在这里,比如一个客户端连接了,$this->socket得到连接请求,所以$this->socket会被选出,然后进入下面的循环,得到一个新的套接字资源,就是这个请求的客户端的套接字资源,下次循环的时候这个客户端套接字资源会进入下方的else
            foreach($cycle as $sock) {
                var_dump($sock);
                if($sock === $this->socket) {//判断是否为服务器的套接字,进入的话表示这个套接字未监听到资源信息
                    $client = socket_accept($this->socket);//接收套接字的资源信息,成功返回套接字的信息资源,失败为false
                    $this->accept[] = $client;
                    $key = array_keys($this->accept);//获取集合的key
                    $this->isHand[$key] = false;//是否已经握手连接
                } else {
                    echo "other socket
";
                    $length = socket_recv($sock, $buffer, 204800, 0);//从已连接的socket接收数据,数据保存在$buffer,返回接收到的字节数。
                    var_dump($length);
                    $key = array_search($sock, $this->accept);//从$this->accept中搜索值$sock返回键
                    var_dump($key);
                    if($length < 7) {//接受到的数据字节数
                        $this->close($sock);
                        continue;
                    }
                    var_dump(!$this->isHand[$key]);
                    var_dump($buffer);
                    if(!$this->isHand[$key]) {
                        $this->dohandshake($sock, $buffer, $key);
                        var_dump("dd");
                    } else {
                        // 先解码,再编码
                        $data = $this->decode($buffer);
                        var_dump($data);
                        $data = $this->encode($data);
                        var_dump($data);
                        // 判断断开连接(断开连接时数据长度小于10)
                        if(strlen($data) > 10) {
                            foreach($this->accept as $client) {
                                socket_write($client, $data, strlen($data));
                            }
                        }
                    }
                }
                var_dump("ee");
            }

        }

    }

 

public function dohandshake($sock, $data, $key) {
    if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $data, $match)) {//获取到Sec-WebSocket-Key
        $response = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));//258EAFA5-E914-47DA-95CA-C5AB0DC85B11 不知道为什么要这个字符串…… 有大神知道的吗?
        $upgrade  = "HTTP/1.1 101 Switching Protocol\r\n" .
            "Upgrade: websocket\r\n" .
            "Connection: Upgrade\r\n" .
            "Sec-WebSocket-Accept: " . $response . "\r\n\r\n";
        socket_write($sock, $upgrade, strlen($upgrade));//握手成功
        $this->isHand[$key] = true;
    }
}

 

/**
 * 解码过程
 */
public function decode($buffer) {
    $len = $masks = $data = $decoded = null;
    $len = ord($buffer[1]) & 127;
    if ($len === 126) {
        $masks = substr($buffer, 4, 4);
        $data = substr($buffer, 8);
    }
    else if ($len === 127) {
        $masks = substr($buffer, 10, 4);
        $data = substr($buffer, 14);
    }
    else {
        $masks = substr($buffer, 2, 4);
        $data = substr($buffer, 6);
    }
    for ($index = 0; $index < strlen($data); $index++) {
        $decoded .= $data[$index] ^ $masks[$index % 4];
    }
    return $decoded;
}

/**
 * 编码过程
 */
public function encode($buffer) {
    $length = strlen($buffer);
    if($length <= 125) {
        return "\x81".chr($length).$buffer;
    } else if($length <= 65535) {
        return "\x81".chr(126).pack("n", $length).$buffer;
    } else {
        return "\x81".char(127).pack("xxxxN", $length).$buffer;
    }
}

转载于:https://my.oschina.net/u/3914215/blog/2966920

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值