为啥握手失败?

Posted

技术标签:

【中文标题】为啥握手失败?【英文标题】:Why is the handshake failing?为什么握手失败? 【发布时间】:2012-04-22 02:49:36 【问题描述】:

我正在使用 websocket4j 库,并查看了有关如何在服务器应用程序中使用它的示例。我从那里获取代码并将其实施到我之前使用原始套接字的当前项目中。无论我使用哪个客户端,我似乎都会收到一个 IOExcpetion 说握手失败。我不知道出了什么问题,因为我从示例服务器中获取了代码(这显然应该可以工作),并且我使用了一个 javascript 示例客户端来确保它不是客户端的错。这是主要方法。

 public static void main(String args[])
        BufferedReader b=new BufferedReader(new InputStreamReader(System.in));
        System.out.print("PORT ( default - 1000 ): ");
        int port=1000;
        try
            port=Integer.parseInt(b.readLine());
        
        catch(Exception e)
            System.out.println("Wrong format. Using 1000 instead");
            port=1000;
        
        System.out.println("Server Started. Waiting for connections");
        try
            WebServerSocket listener=new WebServerSocket(port);
            while(true)
                WebSocket server=listener.accept();
                U413ChatServer connection=new U413ChatServer(server);
                Thread t=new Thread(connection); 
                t.start();
            
        
        catch(Exception e) e.printStackTrace();
        
    

这是屏幕上出现的内容

Server Started. Waiting for connections
java.io.IOException: Handshake failed
        at websocket4j.AbstractWebSocket.<init>(Unknown Source)
        at websocket4j.server.WebSocket.<init>(Unknown Source)
        at websocket4j.server.WebServerSocket.accept(Unknown Source)
        at U413ChatServer.main(U413ChatServer.java:55)
Caused by: java.io.IOException: Unexpected header field: Sec-WebSocket-Key: yfOg
xCbblVyY8ARVFyMtOw==
        at websocket4j.server.WebSocket.handshake(Unknown Source)
        at websocket4j.AbstractWebSocket$HandshakeRunner.run(Unknown Source)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:47
1)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
        at java.util.concurrent.FutureTask.run(FutureTask.java:166)
        at java.lang.Thread.run(Thread.java:722)

第 55 行是:

WebSocket server=listener.accept();

任何帮助将不胜感激

【问题讨论】:

根据堆栈跟踪,U413ChatServer.java 的第 55 行调用了WebServerSocket.accept()。异常似乎发生在这里。 WebSocket 协议中需要标头Sec-WebSocket-Key。见en.wikipedia.org/wiki/WebSocket#WebSocket_protocol_handshake。我想知道为什么会出乎意料 我已经发布了一个答案:客户端和服务器使用不同的 Websocket Protokoll 版本。除了使用不同的服务器实现或不同的客户端实现之外,别无他法。 【参考方案1】:

您的客户端使用的 WebSocket 协议与服务器的协议版本不兼容。

服务器实现过时的(过期:2011 年 2 月 17 日)WebSocket protocol draft-ietf-hybi-thewebsocketprotocol-latest 而您的客户可能会实现类似RFC6455(标准)的东西。

您应该看看其他实现,例如 Netty or the Jetty WebSocketServer

【讨论】:

【参考方案2】:

是的 assylias 是对的。您使用的 websocket4j 套件确实已经过时,需要两个键和令牌值才能做出响应,但由于数字除以零异常或流异常结束而失败。

【讨论】:

以上是关于为啥握手失败?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复“SSL 握手失败”

为啥 java 在 SSL 握手期间不发送客户端证书?

TLS 握手失败,但通信未关闭

ClientHello 后 SSL 握手失败

HttpClient 在 Android 5.0 Lollipop 中因握手失败而失败

Paypal ssl 握手失败