【问题标题】:Connection reset by peer: socket write error对等方重置连接:套接字写入错误
【发布时间】:2012-01-20 16:43:47
【问题描述】:

在运行此代码时,我在最后一个 while 循环中遇到了 OutputStream.write 异常(它在代码中的其他地方运行良好) - 这是在主机中搜索时在 java 中植入代理服务器-响应内容长度并将结果转发到它工作的浏览器,但是当尝试处理“传输编码:分块”策略时,相同的方法不起作用'并抛出此异常:

 java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at IncomingRequest.run(IncomingRequest.java:250)

 is = hostSocket.getInputStream();
            OutputStream os = client.getOutputStream();

            System.out.println("Forwarding request from server");

            byte[] currByte = new byte[1];
            StringBuilder responseHeader = new StringBuilder();
            int crlfCounter = 4;

            // Separates the response header by looking for 2 consecutive \r\n

            while (crlfCounter > 0){
                is.read(currByte);
                os.write(currByte);
                System.out.print((char)currByte[0]);
                responseHeader.append((char)currByte[0]);
                if ((char)currByte[0] == '\r' || (char)currByte[0] == '\n'){
                    crlfCounter--;
                }else{
                    crlfCounter = 4;
                }
            }

            StringBuilder chuckSize = new StringBuilder();
            int contentLength = 0;
            int contentIndex = responseHeader.toString().indexOf("Content-Length: ");
            int chunkedIndex = responseHeader.toString().indexOf("Transfer-Encoding: chunked");
            if (contentIndex != -1) {
                contentIndex += 16;
                int conEnd = responseHeader.toString().indexOf('\n', contentIndex);
                contentLength = Integer.parseInt(responseHeader.toString().substring(contentIndex,conEnd).trim());
                System.out.println("Content Length is : " + contentLength);
                while (contentLength > 0){
                    is.read(currByte);
                    os.write(currByte);
                    contentLength--;
                }
                os.write('\r');
                os.write('\n');
                os.write('\r');
                os.write('\n');
            } else  if (chunkedIndex != -1){
                boolean lastChunk = false;
                while (!lastChunk) {

                    do {
                        is.read(currByte);
                        chuckSize.append((char) currByte[0]);
                    } while ((char)currByte[0] != '\n');

                    contentLength = Integer.parseInt(chuckSize.toString().trim(), 16);
                    System.out.println("Hex " + chuckSize.toString());
                    System.out.println(contentLength + "     the number");

                    if (contentLength == 0) {
                        lastChunk = true;
                    }

                    while (contentLength > 0){
                        is.read(currByte);
                        os.write(currByte);
                        contentLength--;
                    }
                }
            }

【问题讨论】:

    标签: java socket.io proxy-server


    【解决方案1】:

    我可能误读了您的代码,但您似乎将所有标头(包括“Transfer-Encoding:chunked”)写入os,但您没有写入实际的块大小,因此接收端可能会关闭非法输入导致的连接(期望块大小,获取其他数据)

    【讨论】:

    • 谢谢,成功了,错过了:) 现在提取块大小的逻辑似乎有问题......
    • 最后一个输入是十六进制 A,这是我得到异常的数字 10-Exception in thread "Thread-11" java.lang.NumberFormatException: For input string: "" at java.lang.NumberFormatException.forInputString(Unknown Source) at java.lang.Integer.parseInt(Unknown Source) at IncomingRequest.run(IncomingRequest.java:252)
    • 好的,新异常是由于我没有在此处复制的其余代码中的错误比较造成的。非常感谢您提供了很多帮助!
    • @Rona 如果这个答案是正确的,请accept it。 ;)
    • 哇,我已经一年没有登录了,错过了所有的乐趣:) 要解析十六进制 int,请将基数 16 作为第二个参数传递给 parseInt docs.oracle.com/javase/6/docs/api/java/lang/…, int)
    猜你喜欢
    • 2016-04-12
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多