救救心累的宝宝我

救救心累的宝宝我 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑

在吗?好像每个都画不出来。我该怎么改呢?

在吗?好像每个都画不出来。我该怎么改呢?

在吗?好像每个都画不出来。我该怎么改呢?

在吗?好像每个都画不出来。我该怎么改呢?

在吗?好像每个都画不出来。我该怎么改呢?

个人动态

救救心累的宝宝我 关注了用户 · 9月3日

唯一丶 @weiyi_5b04fb4aa815a

关注 134

救救心累的宝宝我 赞了回答 · 9月3日

解决做一个php socket 向 websocket 传送数据的简单程序,想了解核心,在帧处理这里我搞不懂,麻烦解释一下

以下内容仅为查阅相关资料后得出的结论,如果错误请指出。

仅作为学习参考,如需用于生产,请选择已有的一些解决方案。

图片.png
问题1:
在完成握手后, socket_read 开始阻塞接受输入,输入完成后发给浏览器后,就又回到了上面的 接受客户端连接,所以 你就只能发送一条消息,如果要想一直发送,就需要把 正式开始通信那一部分放进 while true 里面,让他一直阻塞接受输入。就可以一直发送消息了。

图片.png

问题2:
关于第二个问题问题,详见RFC 6455

Payload length: 7 bits, 7+16 bits, or 7+64 bits
  The length of the "Payload data", in bytes: if 0-125, that is the
  payload length.  If 126, the following 2 bytes interpreted as a
  16-bit unsigned integer are the payload length.  If 127, the
  following 8 bytes interpreted as a 64-bit unsigned integer (the
  most significant bit MUST be 0) are the payload length.  Multibyte
  length quantities are expressed in network byte order.  Note that
  in all cases, the minimal number of bytes MUST be used to encode
  the length, for example, the length of a 124-byte-long string
  can't be encoded as the sequence 126, 0, 124.  The payload length
  is the length of the "Extension data" + the length of the
  "Application data".  The length of the "Extension data" may be
  zero, in which case the payload length is the length of the
  "Application data".

问题3:
发送中文在发送时是对的,但是浏览器在接受到响应后会发生 Could not decode a text frame as UTF-8. 错误。这是服务器在接收数据时被拆分成了几个帧(通常是发送的数据太长,在 socket_read 时被当成了几个帧接收(见2),此时是按照帧进行回复的,因为读取并不一定恰好是一个完整的汉字,就造成了 utf-8 编码错误。)

关于 socket 相关例子请查阅

关注 2 回答 1

救救心累的宝宝我 提出了问题 · 9月3日

解决做一个php socket 向 websocket 传送数据的简单程序,想了解核心,在帧处理这里我搞不懂,麻烦解释一下

有三个疑问:

1.连接成功后,我想服务器发送消息,为什么只有第一次服务器会返回信息
2.第一次向服务器发送信息,服务器会返回信息,但是返回的信息是125个字符的,并不是一次返回全部,如图image.png
3.为什么发汉字多了会报错,服务器直接关闭,发几个字不会image.png
image.png

> 这是服务器代码,php的

<?php
set_time_limit(0);
$address = '127.0.0.1';
$port = '231';
if( ($sock = socket_create( AF_INET, SOCK_STREAM, SOL_TCP )) === false ) die( "套接字创建失败:" . socket_strerror(socket_last_error( )) );
if ( ($ok = socket_bind( $sock , $address , $port )) === false ) die( "服务器绑定失败:" . mb_convert_encoding(socket_strerror( socket_last_error( $sock )) , "utf-8","GBK") );
if ( socket_listen($sock, 4) === false )  die( "服务器监听失败:" . socket_strerror( socket_last_error( $sock ) ) );
 print_r('服务器开启成功');
while (true){
    if (($client = socket_accept($sock)) === false) die( "套接字接收客户端创建失败:" . socket_strerror(socket_last_error( $sock )) );
    $buf = socket_read($client, 8192);    //读取请求
    $response = hand_shake($buf);    //跟websocket握手
    socket_write($client,$response,strlen($response));//发送响应
    //正式开始通信...
    $msg = socket_read($client, 8192);
    $msg = frame(decode($msg));
    socket_write($client, $msg, strlen($msg));
    //$msg = code($msg);
    //if( socket_write($client,$msg,strlen($msg)) === false ) die("socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."/n"); //发送数据
    //else echo'发送信息成功';
    //socket_close($client);  
}
//socket_close($sock);  

function hand_shake($buf){
    $buf  = substr($buf,strpos($buf,'Sec-WebSocket-Key:')+18);
    $key  = trim(substr($buf,0,strpos($buf,"\r\n")));
    $new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
    $new_message = "HTTP/1.1 101 Switching Protocols\r\n";
    $new_message .= "Upgrade: websocket\r\n";
    $new_message .= "Sec-WebSocket-Version: 13\r\n";
    $new_message .= "Connection: Upgrade\r\n";
    $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
    return $new_message;
}

// 解析数据帧
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;
}
// 返回帧信息处理
function frame($s) {
    $a = str_split($s, 125);
    if (count($a) == 1) {
        return "\x81" . chr(strlen($a[0])) . $a[0];
    }
    $ns = "";
    foreach ($a as $o) {
        $ns .= "\x81" . chr(strlen($o)) . $o;
    }
    return $ns;
}

// 返回数据
function send($client, $msg){
    $msg = $this->frame($msg);
    socket_write($client, $msg, strlen($msg));
}

?>
前端代码

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
</head>
<body>
<div style="width:410px;height:500px;margin:0 auto;">
<h2>超迷你简易网页聊天</h2>
<textarea  id="history" style="width:400px;height:300px;padidng:10px;font:16px/24px '宋体';display:block;margin-bottom:20px;" readonly="readonly"></textarea>
<select name="" style="width:60px;height:35px;"><option value="妈妈" selected>妈妈</option><option value="爸爸">爸爸</option></select><input  id="cont" type="text" style="width:260px;height:30px;" placeholder="输入内容">
<input  id="send" type="button" value="发送" style="width:70px;height:35px;">
</div>
<script>
function $(ele){
    return document.getElementById(ele);
}
var ws = new WebSocket("ws://127.0.0.1:231");
ws.onopen = function(){   log("连接服务器成功");        }
ws.onerror = function(){    log("连接服务器失败");        }
ws.onclose = function(){    log("服务器已关闭");        }
$('send').onclick = function(){
    ws.send( $('cont').value );
    ws.onmessage = function(e){
        log('新消息:'+ e.data);
      }
}
function log(html){    $('history').value += '->'+html+'\n' ;        }
</script>
</body>

关注 2 回答 1

救救心累的宝宝我 赞了回答 · 9月2日

解决用 php 写了个 WebSocket 服务端,在 IE 下出现了问题

现在版本(13)的websocket是会把客户端send()的信息做mask处理,然后传给服务端。所以服务端要是直接echo客户端传来的信息是会显示乱码的。想要正常显示要转换,同样服务端传给客户端的信息根据字数的长度(len<=125,125<len<=65535,len>65535)需要经过不同处理。上面的代码的问题是服务端直接把客户端传来的信息发给客户端,所以才会出现"must not mask"。
ps:果然英语对程序员来说很重要。

关注 3 回答 2

救救心累的宝宝我 关注了问题 · 9月2日

解决js如何删掉选中的文本,就像用js执行"鼠标选中文本,然后剪切"这个操作?

js可以替换或删掉选中文本吗?是否要给文本节点添加onfocus事件。

关注 4 回答 2

救救心累的宝宝我 关注了专栏 · 9月2日

小胡子哥(Barret Lee)

声明:无特殊说明文章皆为原创,部分同步自我的个人网站:http://barretlee.com.

关注 41

救救心累的宝宝我 提出了问题 · 8月31日

php socket udp连接使用场景有哪些?? 尝试 websocket才发现websocket只支持tcp 的socket

那么php udp是否有 可用之处呢?做游戏服务器,他效率不行,想着结合websocket做个聊天室,他又不支持

关注 2 回答 1

救救心累的宝宝我 赞了回答 · 3月5日

php怎么获取当前域名的主机名?

echo explode('.',$_SERVER['SERVER_NAME'])[1];

关注 2 回答 1

救救心累的宝宝我 赞了回答 · 3月4日

请用最多两行代码提取出来字符串其中的所有img标签,并显示出来

代码多了,会影响性能吗?还是代码越少体现水平越高吗?

关注 2 回答 2

救救心累的宝宝我 赞了回答 · 2月21日

请问正则如何判断图片标签带有http://呢,没有自动补上

思路:

  1. 以images为分界,来切割src的内容
  2. 得到的数组,第1个元素为images之前的内容,第二个元素为images之后的内容
  3. 全部重新替换images之前的内容。当然你也可以根据需要判断是否有http,没有的话,再替换
 const imgs = document.querySelectorAll("img")
    imgs.forEach((item, index) => {
      let imgSrc = item.getAttribute("src")
      const arr = imgSrc.split('images')
      arr[0] = `${window.location.origin}${window.location.pathname}${window.location.search}`
      imgSrc = arr.join("")
      item.setAttribute("src", imgSrc)
    })

关注 3 回答 3

认证与成就

  • 获得 8 次点赞
  • 获得 72 枚徽章 获得 0 枚金徽章, 获得 8 枚银徽章, 获得 64 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-09-02
个人主页被 711 人浏览