Chrome(客户端)和热点(服务器)之间的Websocket通信(状态行不会以CRLF结束) [英] Websocket communication between chrome(client) and hotspot(server) (Status line does not end with CRLF)

查看:145
本文介绍了Chrome(客户端)和热点(服务器)之间的Websocket通信(状态行不会以CRLF结束)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的:


  • 我为我的手机创建了Android应用程序,并且我正在使用来自Google Play的应用程序作为服务器

  • 我打开我的热点,用户可以通过ip和端口访问我的wifi,例如:192.168.xxx.xxx:8080


他会看到我的网站。在那里,我使用websockets在JavaScript和android java之间传递数据。



在Firefox和Explorer中,它可以正常工作,但在Chrome中告诉我:
Websocket连接到'ws://192.168.xxx.xxx:9999 /'失败:Websocket握手期间出错:状态行不以CRLF结束。



我用过来自这里的代码:编写WebSocket服务器
(参见下面的文件编辑)。



另外我读了RFC 6455: https://tools.ietf.org/html/rfc6455 ,我完全一样写在那里。



这个例子 ClientSession

  import java.io.BufferedReader; 
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
导入java.net.Socket;

公共类ClientSession {

专用套接字套接字;
$ b $ public ClientSession(Socket套接字){
System.out.println(new ClientSessionTest());
this.socket = socket;
initClientListener();


private void initClientListener(){
System.out.println(initClientListener());
Thread t = new Thread(new Runnable(){
$ b $ @Override
public void run(){
try {
BufferedReader socketReader = new BufferedReader (
new InputStreamReader(socket.getInputStream()));
final PrintWriter socketWriter = new PrintWriter(socket
.getOutputStream(),true);
String clientKey = null;
String responseKey = null;
while(true){
String line = socketReader.readLine();
if(line == null){
System.out。 println(从客户端收到null - 关闭连接);
break;
} else if(line.isEmpty()){
System.out.println(empty line);

String _01 =HTTP / 1.1 101交换协议;
String _02 =升级:websocket;
String _03 =连接:升级;
String _04 =Sec-WebSocket-Accept:+ responseKey;
String _05 =Sec-WebSocket-Protocol:chat;
String _06 =Content-Encoding:identity;

System.out.println(_01);
System.out.println(_02);
System.out.println(_03);
System.out.println(_04);
System.out.println(_05);
System.out.println(_06);
System.out.println();

socketWriter.println(_01);
socketWriter.println(_02);
socketWriter.println(_03);
socketWriter.println(_04);
socketWriter.println(_05);
socketWriter.println(_06);
socketWriter.println();

// ********************来自客户端的数据***************** ****

尝试{
byte [] buff = new byte [100];
int length = socket.getInputStream()。read(buff);

byte [] bstr = new byte [length];
System.arraycopy(buff,0,bstr,0,length);
System.out.println(new String(bstr));
for(byte b:bstr){
System.out.print(((int)b)+);
}
System.out.println();
System.out.println();
String str = new String(decodeFrame(buff),UTF-8);
System.out.println(str);
} catch(Exception e){
System.out.println(e.getMessage());

// **************************************** ****************


} else if(line.startsWith(Sec-WebSocket-Key:)){
clientKey = line.replace(Sec-WebSocket-Key:,);
responseKey = ResponseGenerator
.toResponseKey(clientKey);
} else {
System.out.println(+ line);
//socketWriter.println(\"lala);
}

}
} catch(IOException e){
e.printStackTrace();
}

}
});
t.start();
}

我改了这行 String _01 =HTTP / 1.1 101 Switching协议; String _01 =HTTP / 1.1 101 Switching Protocols \r\\\
;
和它删除我上面写的错误(CRLF),但从onopen方法JavaScript代码(下面)不会触发,之后Firefox和资源管理器也不能正常工作。


Javascript:

 < HTML> 
< head>

< script type =text / javascript>

var websocket;
var url =ws:// localhost:1234;

函数init(){
尝试{
websocket = new MozWebSocket(url,chat);
} catch(e){
websocket = new WebSocket(url,char);
}

websocket.onopen = function(evt){onOpen(evt)};
websocket.onclose = function(evt){onClose(evt)};
websocket.onmessage = function(evt){onMessage(evt)};
websocket.onerror = function(evt){onError(evt)};
}

var count = 0;
函数loop(){
var message =lala\\\
;
websocket.send(message);
count ++;

setTimeout(loop,500);
}

function onOpen(event){
alert(Socket has been opened!+('5'+ 3)+('5' - 3));

loop();
}

函数onMessage(evt){
alert(evt);
}

函数onClose(event){
alert(socket closed);
}

function onError(event){
alert(event.data);
}

window.addEventListener(load,init,false);


< / script>

< / head>
< body>



< / body>
< / html>

注意:

我没有互联网连接(无线或3G)在我的手机。连接只是从用户到我的访问点。

解决方案

我认为这个错误有点误导。看起来,每个标题都应该以CRLF结束,而不仅仅是第一个标题(状态行)。至少根据测试用例

  String _01 =HTTP / 1.1 101 Switching Protocols \r; //在这里添加\r。 
String _02 =Upgrade:websocket \r; //在这里添加\r。
String _03 =Connection:Upgrade \r; //在这里添加\r。
String _04 =Sec-WebSocket-Accept:+ responseKey +\r; //在这里添加\r。
String _05 =Sec-WebSocket-Protocol:chat \r; //在这里添加\r。
String _06 =Content-Encoding:identity \r; //在这里添加\r。

另外,在最后一个 socketWriter.println( ) -

  socketWriter.println(\r); //在这里添加\r。 

也许它会将其标记为响应的结束。



另外,您可以使用 Fiddler2 (或 Wireshark ,但它太冗长)来比较WebSocket实现(网络数据)和一个可以工作的人


this is what i have:

  • I created android app for my mobile and i'm using app from google play as a server
  • I open my hotspot and user can access my wifi with ip and port for example: 192.168.xxx.xxx:8080

He will see my website. There i'm using websockets to pass data between javascript and android java.

In Firefox and Explorer it works fine, but in Chrome it tells me: "Websocket connection to 'ws://192.168.xxx.xxx:9999/' failed: Error during websocket handshake: Status line does not end wit CRLF".

I used the code from here: Writing a WebSocket Server (See file below "EDIT").

Also i read RFC 6455: https://tools.ietf.org/html/rfc6455 and i do exactly as wrote there.

This example of the ClientSession:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ClientSession {

    private Socket socket;

    public ClientSession(Socket socket) {
        System.out.println("new ClientSessionTest()");
        this.socket = socket;
        initClientListener();
    }

    private void initClientListener() {
        System.out.println("initClientListener()");
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    BufferedReader socketReader = new BufferedReader(
                            new InputStreamReader(socket.getInputStream()));
                    final PrintWriter socketWriter = new PrintWriter(socket
                            .getOutputStream(), true);
                    String clientKey = null;
                    String responseKey = null;
                    while (true) {
                        String line = socketReader.readLine();
                        if (line == null) {
                            System.out.println("received null from client - closing connection");
                            break;
                        } else if (line.isEmpty()) {
                            System.out.println("empty line");

                            String _01 = "HTTP/1.1 101 Switching Protocols";
                            String _02 = "Upgrade: websocket";
                            String _03 = "Connection: Upgrade";
                            String _04 = "Sec-WebSocket-Accept: " + responseKey;
                            String _05 = "Sec-WebSocket-Protocol: chat";
                            String _06 = "Content-Encoding: identity";

                            System.out.println(_01);
                            System.out.println(_02);
                            System.out.println(_03);
                            System.out.println(_04);
                            System.out.println(_05);
                            System.out.println(_06);
                            System.out.println("");

                            socketWriter.println(_01);
                            socketWriter.println(_02);
                            socketWriter.println(_03);
                            socketWriter.println(_04);
                            socketWriter.println(_05);
                            socketWriter.println(_06);
                            socketWriter.println("");

                            //********************data from client*********************

                            try {
                                byte[] buff = new byte[100];
                                int length = socket.getInputStream().read(buff);

                                byte[] bstr = new byte[length];
                                System.arraycopy(buff, 0, bstr, 0, length);
                                System.out.println(new String(bstr));
                                for (byte b : bstr) {
                                    System.out.print(((int) b) + " ");
                                }
                                System.out.println();
                                System.out.println();
                                String str = new String(decodeFrame(buff),"UTF-8");
                                System.out.println(str);
                            } catch (Exception e) {
                                System.out.println(e.getMessage());

                            //********************************************************

                        }
                        } else if (line.startsWith("Sec-WebSocket-Key:")) {
                            clientKey = line.replace("Sec-WebSocket-Key: ", "");
                            responseKey = ResponseGenerator
                                    .toResponseKey(clientKey);
                        } else {
                            System.out.println("" + line);
                            //socketWriter.println("lala");
                        }

                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
        t.start();
    }

I changed the line String _01 = "HTTP/1.1 101 Switching Protocols"; to String _01 = "HTTP/1.1 101 Switching Protocols\r\n"; and its remove the error (CRLF) i wrote above but the onopen method from the javascript code (below) is not firing and after that also Firefox and Explorer are not working.

Javascript:

<html>
<head>

<script type="text/javascript" >

var websocket;
var url = "ws://localhost:1234";

function init(){
        try{
                websocket = new MozWebSocket(url, "chat");
        }catch(e){
                websocket = new WebSocket(url, "char");
        }

        websocket.onopen = function(evt) { onOpen(evt) };
        websocket.onclose = function(evt) { onClose(evt) };
        websocket.onmessage = function(evt) { onMessage(evt) };
        websocket.onerror = function(evt) { onError(evt) };
}

var count = 0;
function loop(){
        var message = "lala\n";
        websocket.send(message);
        count++;

        setTimeout(loop, 500);
}

function onOpen(event){  
    alert("Socket has been opened!" + ('5' + 3) + ('5' - 3));  

    loop();
}  

function onMessage(evt){  
    alert(evt);  
}  

function onClose(event){  
    alert("socket closed");  
}

function onError(event){
        alert(event.data);
}

window.addEventListener("load", init, false);


</script>

</head>
<body>



</body>
</html>

Notice:

I dont have an internet connection (no wifi or 3g) in my mobile. the connection is only from the user to my access point.

解决方案

I think the error is a bit misleading. Every header should end with CRLF and not only the first one (the 'status line'), it seems. At least according to the test case.

String _01 = "HTTP/1.1 101 Switching Protocols\r"; // Added \r here.
String _02 = "Upgrade: websocket\r"; // Added \r here.
String _03 = "Connection: Upgrade\r"; // Added \r here.
String _04 = "Sec-WebSocket-Accept: " + responseKey + "\r"; // Added \r here.
String _05 = "Sec-WebSocket-Protocol: chat\r"; // Added \r here.
String _06 = "Content-Encoding: identity\r"; // Added \r here.

Also, add another \r in the last socketWriter.println("") -

socketWriter.println("\r"); // Added \r here.

Perhaps it will mark it as the end of the response.

Also, you can use Fiddler2 (or Wireshark, but it is too verbose) to compare the differences between your WebSocket implementation (in terms of the network data) and one that works.

这篇关于Chrome(客户端)和热点(服务器)之间的Websocket通信(状态行不会以CRLF结束)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆