通过Weberknecht连接到WebSocket时的ArrayIndexOutOfBoundsException

时间:2012-11-04 01:53:10

标签: java android websocket

我正在尝试通过Weberknecht Java library连接到WebSocket。当Java客户端尝试创建连接时,我收到以下错误消息:

W/System.err(805): java.lang.ArrayIndexOutOfBoundsException: length=1000; index=1000
W/System.err(805): at ...WebSocketConnection.connect(WebSocketConnection.java:86)

以下是导致问题的部分:

public void connect() throws WebSocketException {
    try {
        if (connected) {
            throw new WebSocketException("already connected");
        }

        socket = createSocket();
        input = new DataInputStream(socket.getInputStream());
        output = new PrintStream(socket.getOutputStream());

        output.write(handshake.getHandshake());

        boolean handshakeComplete = false;
        int len = 10000;
        byte[] buffer = new byte[len];
        int pos = 0;
        ArrayList<String> handshakeLines = new ArrayList<String>();

        while (!handshakeComplete) {
            int b = input.read();
            buffer[pos] = (byte) b; // THIS LINE CAUSES THE EXCEPTION
            pos += 1;

            if (buffer[pos - 1] == 0x0A && buffer[pos - 2] == 0x0D) {
                String line = new String(buffer, "UTF-8");
                if (line.trim().equals("")) {
                    handshakeComplete = true;
                } else {
                    handshakeLines.add(line.trim());
                }

                buffer = new byte[len];
                pos = 0;
            }
        }

可能导致此问题的原因是什么?是否此客户端库可能不符合服务器使用的WebSocket版本?

issue over there at Weberknecht尚未解决。我想在这里提出这个问题,因为它似乎是一个非常普遍的问题(阅读WebSocket标题和握手数据)。

3 个答案:

答案 0 :(得分:1)

代码需要从input.read()检查-1以表示连接到EOF。

此外,我将假设基于相同的代码位,如果在10000字节之后没有到达握手,则它是无效的握手。

while (!handshakeComplete) {
            int b = input.read();

            if (b == -1)
                throw new WebSocketException ("Connected closed.");                

            if (pos == buffer.length)
                throw new WebSocketException ("Invalid handshake.");

            buffer[pos] = (byte) b; // THIS LINE CAUSES THE EXCEPTION
            pos += 1;

            if (buffer[pos - 1] == 0x0A && buffer[pos - 2] == 0x0D) {
                String line = new String(buffer, "UTF-8");
                if (line.trim().equals("")) {
                    handshakeComplete = true;
                } else {
                    handshakeLines.add(line.trim());
                }

                buffer = new byte[len];
                pos = 0;
            }
        }

更新

这是一个更好的实现:

public void connect() throws WebSocketException {
    try {
        if (connected) {
            throw new WebSocketException("already connected");
        }

        socket = createSocket();
        input = new DataInputStream(socket.getInputStream());
        output = new PrintStream(socket.getOutputStream());

        output.write(handshake.getHandshake());

        boolean handshakeComplete = false;

        ArrayList<String> handshakeLines = new ArrayList<String>();

        BufferedReader reader = new BufferedReader(input);

        String handshakeData;
        while ((handshakeData = reader.readLine()) != null) {
            if (handshakeData.trim().equals("")) {
               handshakeComplete = true;
               break;
            }
            handshakeLines.add(handshakeData);
        }

        if (!handshakeComplete)
            throw new WebSocketException ("Failed to establish handshake.");

答案 1 :(得分:1)

我只是想,你为什么不使用为你读取字节的int read(byte[] b)int read(byte[] b) --> Reads some number of bytes from the contained input stream and stores them into the buffer array b.

 while (!handshakeComplete) {
   int bytesRead = input.read(buffer);//returns number of bytes read
   if(bytesRead  < 10000 || bytesRead == -1 ||
      (buffer[bytesRead - 1] == 0x0A && buffer[bytesRead - 2] == 0x0D)){
        //done with reading
        handshakeComplete = true;
   }
   if(bytesRead != -1){
      String line = new String(buffer, "UTF-8");
      if (!line.trim().equals("")) {
         handshakeLines.add(line.trim());
      }
   }
 }

答案 2 :(得分:0)

只是简单地看一下,你不能保证在buffer.length == pos之前停下来。这需要仔细检查一件事 - pos必须严格保持小于缓冲区的长度。