设为首页 收藏本站
查看: 934|回复: 0

[经验分享] websocket draft-15 服务端握手Demo的perl实现

[复制链接]

尚未签到

发表于 2015-12-26 10:32:28 | 显示全部楼层 |阅读模式
  websocket这个坑爹的项目一直都在草案中,而且有时的更新变化还挺大的。目前最新的版本要先握手,信任后再发送相应数据,数据还掩码了。这次先实现了握手功能,其原理如下:
  1.客端向服务器端发送类似这样的HTTP头:

  


        GET / HTTP/1.1
        Upgrade: websocket
        Connection: Upgrade
        Host: localhost:8000
        Sec-WebSocket-Origin: null
        Sec-WebSocket-Key: FcJ21uh+iiDs7haoaG1cKQ==
        Sec-WebSocket-Version: 8  
  
  其中
  Upgrade:wesocket 描述了该信息是websocket协议,
  Host:localhost:8000 这个就是请求的主机地址和端口号,
  Sec-WebSocket-Version:8 是版本号,这里是8,用的chrome14作的测试

  Sec-WebSocket-Key: FcJ21uh+iiDs7haoaG1cKQ== 这条是很重要的,FcJ21uh+iiDs7haoaG1cKQ==是客户端提供的握手所用的key,需要服务器端根据该key作相应计算后返回一个对应的key来完成握手,具体的计算方法马上就会说到。

  
  2. 服务器端

        服务器端接收到请求的数据后,先根据头来判断是否为websocket协议,是的话就会先作握手处理,然后再进行数据的相互发送,这里先只讨论握手,数据发送的内容下次再说了。。。。  握手步骤:
  (1)服务器端获取到客户端发送过来的 Sec-WebSocket-Key 值(比如这里的 FcJ21uh+iiDs7haoaG1cKQ== );

  (2)将获取到的key值与一个magic string “258EAFA5-E914-47DA-95CA-C5AB0DC85B11” 连接成一个新的key串 "FcJ21uh+iiDs7haoaG1cKQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11",这个magic string为标准里给出的值,可以看作为一个唯一ID序列;
  (3)将新生成的串进行SHA1编码,生成一个由多组两位16进制数构成的加密串,比如这里的 "FcJ21uh+iiDs7haoaG1cKQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 将生成 "11a8a543955aaf7f9a266c55b2a9cda3151cdec5";

  (4)把加密串按2位16进制数字分隔,进行base64编码生成最终的key:base64编码(11 a8 a5 43 95 5a af 7f 9a 26 6c 55 b2 a9 cd a3 15 1c de c5);
  (5)将最终生成的key以Sec-WebSocket-Accept:key值 整合到返回头中返回给客户端(该例子的key计算结果为 EailQ5Var3+aJmxVsqnNoxUc3sU=):
  
  

            HTTP/1.1 101 Web Socket Protocol Handshake
            Upgrade: websocket
            Connection: Upgrade
            Sec-WebSocket-Accept: EailQ5Var3+aJmxVsqnNoxUc3sU=
            WebSocket-Origin: localhost
            WebSocket-Location: ws://localhost:8000  
  服务端应答后就完成了这一次的握手,完整代码如下:
  


#!perl -w
use strict;

use IO::Handle;
use Socket;
use Digest::SHA1 qw(sha1 sha1_hex sha1_base64);
use MIME::Base64;

my $buff;
my $port=8000;
my $host='localhost';
my $packhost=inet_aton($host);
my $address=sockaddr_in($port,$packhost);
my $msg="";
my $magicString="258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
my $serverKey="";

sub getClientKey{
    my $ret="";
    if($_[0]=~m"Sec-WebSocket-Key: ([^\s]*)"s){
        $ret=$1;
    }else{
        #print "no matched";
    }
   
    $ret=~s/\s//g;
    return $ret;
}

sub formatSHA1Hex{
    my $ret="";
    my $len=length($_[0]);
    my $i;

    for($i=0;$i<$len;$i+=2){
        $ret.=chr(oct("0x".substr($_[0],$i,2)));
    }

    return $ret;
}

socket(SERVER,AF_INET,SOCK_STREAM,getprotobyname('tcp'));
bind(SERVER,$address);
listen(SERVER,10);

while(1){
    accept(CLIENT,SERVER);
    sysread(CLIENT,$buff,1000);
    $serverKey=encode_base64(formatSHA1Hex(sha1_hex(getClientKey($buff).$magicString)));
    print "$buff\n";

    $msg="HTTP/1.1 101 Web Socket Protocol Handshake\r\n".
            "Upgrade: websocket\r\n".
            "Connection: Upgrade\r\n".
            "Sec-WebSocket-Accept: ".$serverKey."\r\n".
            "WebSocket-Origin: $host\r\n".
            "WebSocket-Location: ws://$host:$port\r\n\r\n";

    CLIENT->autoflush(1);
    syswrite(CLIENT,$msg);
    close CLIENT;
}
close SERVER;
exit 1;  
  为了让代码尽量简单,省去了websockt协议验证之类的细节部分,只列出了核心功能。而且此次只实现了握手部分,而且比较简单,数据相互通信的部分看哪天又闲得蛋疼的时候再写了。。。
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-156469-1-1.html 上篇帖子: perl的package和module 下篇帖子: Perl tracert
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表