简体   繁体   English

读取输入流时出错:软件导致连接中止'在java服务器中

[英]Error while reading inputstream : Software caused connection abort' in java server

I am basically trying to host a server on an Android Device. 我基本上试图在Android设备上托管服务器。 Client devices connect to the server over TCP and send requests. 客户端设备通过TCP连接到服务器并发送请求。 The server performs the action requested by the client and then writes data back to the socket. 服务器执行客户端请求的操作,然后将数据写回套接字。 The connection is not terminated by the server and requests are to be continuously read over the socket and replied to. 连接未被服务器终止,并且将通过套接字连续读取请求并回复。

Note: The first 4 bytes of each request message contain the length of the actual message/request. 注意:每个请求消息的前4个字节包含实际消息/请求的长度。

The parseXmlInputAndExecuteCmd function executes various asynchronous operations depending on the content of the input XML string. parseXmlInputAndExecuteCmd函数根据输入XML字符串的内容执行各种异步操作。 This eventually causes a change in the boolean value of 'allowResponse' variable to true and a certain response is generated which is stored in the variable of type String called 'response'. 这最终会导致'allowResponse'变量的布尔值更改为true,并生成某个响应,该响应存储在名为'response'的String类型的变量中。 Once the boolean 'allowResponse' becomes true, the thread resumes execution and writes the response back to the socket's OutputStream 一旦布尔值'allowResponse'变为true,线程就会恢复执行并将响应写回套接字的OutputStream

Some of these asynchronous operations include connecting and disconnecting from the corporate VPN. 其中一些异步操作包括连接和断开与公司VPN的连接。 Could that be a cause of the error ? 这可能是错误的原因吗?

Some Class level variables being used are : 使用的一些类级变量是:

private volatile boolean allowResponse = false;
private String response;

Server Code: 服务器代码:

    private void startServer() {
    try {
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true) {
            Socket connectionSocket = serverSocket.accept();
            BufferedInputStream bufInpStream = new BufferedInputStream(connectionSocket.getInputStream());
            BufferedOutputStream bufOutStream = new BufferedOutputStream(connectionSocket.getOutputStream());
            ByteArrayOutputStream contentLengthBaos = new ByteArrayOutputStream();
            int c;
            int count = 0;
            while ((c = bufInpStream.read()) != -1) {
                contentLengthBaos.write(c);
                count++;
                if (count == 4) {
                    int contLen = getMessageLength(contentLengthBaos);
                    String content = getMessageContent(bufInpStream, contLen);
                    parseXmlInputAndExecuteCmd(content);
                    count = 0;
                    while (!allowResponse) {
                        Thread.sleep(1000);
                    }
                    allowResponse = false;
                    byte[] responseDataBytes = response.getBytes();
                    int outputContLen = responseDataBytes.length;
                    byte[] contLengthBytes = ByteBuffer.allocate(4).putInt(outputContLen).array();
                    ByteArrayOutputStream o = new ByteArrayOutputStream();
                    o.write(contLengthBytes);
                    o.write(responseDataBytes);
                    byte finalOutPutBytes[] = o.toByteArray();
                    bufOutStream.write(finalOutPutBytes);
                    bufOutStream.flush();
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

@NonNull
private String getMessageContent(BufferedInputStream inFromClient, int contLen) throws IOException {
    ByteArrayOutputStream contentBaos = new ByteArrayOutputStream();
    byte[] contentBytes = new byte[contLen];
    for (int i = 0; i < contLen; i++) {
        contentBaos.write(inFromClient.read());
        ByteArrayInputStream bais = new ByteArrayInputStream(contentBaos.toByteArray());
        bais.read(contentBytes);
    }
    String content = new String(contentBytes);
    Log.d(TAG, "Content : " + content);
    return content;
}

private int getMessageLength(ByteArrayOutputStream contentLengthBaos) {
    byte[] firstFourBytesArr = contentLengthBaos.toByteArray();
    int contLen = new BigInteger(firstFourBytesArr).intValue();
    contentLengthBaos = new ByteArrayOutputStream();
    Log.d(TAG, "Content length: " + contLen);
    return contLen;
}

The server is started using the following lines of code: 使用以下代码行启动服务器:

Thread serverThread = new Thread(new Runnable() {
        @Override
        public void run() {
            startServer();
        }
    });
    serverThread.start();

I am getting the following error stack trace: 我收到以下错误堆栈跟踪:

W/System.err: java.net.SocketException: Software caused connection abort
                  at java.net.SocketInputStream.socketRead0(Native Method)
                  at java.net.SocketInputStream.socketRead(SocketInputStream.java:114)
W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:170)
W/System.err:     at java.net.SocketInputStream.read(SocketInputStream.java:139)
W/System.err:     at java.io.BufferedInputStream.fill(BufferedInputStream.java:248)
W/System.err:     at java.io.BufferedInputStream.read(BufferedInputStream.java:267)
                  at com.example.umathur.myapplication.MainActivity.startServer(MainActivity.java:192)
                  at com.example.umathur.myapplication.MainActivity.access$000(MainActivity.java:61)
                  at com.example.umathur.myapplication.MainActivity$1.run(MainActivity.java:139)
                  at java.lang.Thread.run(Thread.java:764)

I am getting an error called: java.net.SocketException: Software caused connection abort 我收到一个错误: java.net.SocketException: Software caused connection abort

I'm not sure where I'm going wrong in the usage of the inputstream/outputstream. 我不确定在输入流/输出流的使用中我出错了。 Im getting the error at the following line(Line number 192 as mentioned in the stacktrace) : 我在以下行获取错误(堆栈跟踪中提到的行号192):

while ((c = inputStream.read()) != -1)

In some similar questions on StackOverflow, I saw people stating that it might be a corporate firewall configuration issue ? 在StackOverflow的一些类似问题中,我看到有人说这可能是企业防火墙配置问题? Is that correct ? 那是对的吗 ? If so, how do I get it fixed ? 如果是这样,我该如何解决?

Could this be an issue with the Client code (To which I don't have access) not being written correctly ? 这可能是客户端代码(我无权访问)无法正确写入的问题吗?

I can't reproduce your issue locally, and something tells me that your trigger conditions are pretty specific, but here are a few things to try to help you diagnose and fix your problem. 我无法在本地重现您的问题,并且有些东西告诉我您的触发条件非常具体,但这里有一些可以帮助您诊断和解决问题的方法。

  1. Your code: If it's your code, then existing web server code should work. 您的代码:如果它是您的代码,那么现有的Web服务器代码应该可以运行。 Try the code in the code from this nice minimal Medium article on how to create your own Java web server . 尝试使用这篇关于如何创建自己的Java Web服务器的简短介质文章中的代码。
  2. The Firewall: If it's the firewall, contact your network admin person/team etc. If you don't know who it is, just talk to as high profile a person in your company that you feel comfortable asking and they should be able to direct you to the right person. 防火墙:如果它是防火墙,请联系您的网络管理员/团队等。如果您不知道它是谁,只需与贵公司的高调交谈,您觉得他们觉得很自在,他们应该能够指导你是对的人。
  3. Socket SO_KEEPALIVE Option: I found an interesting SuperUser question on the subject , and read that this issue may be caused by the fact that you don't have the SO_KEEPALIVE flag set on your socket. 套接字SO_KEEPALIVE选项:在这个主题上发现了一个有趣的超级用户问题 ,并且读到这个问题可能是因为你没有在套接字上设置SO_KEEPALIVE标志 The answer talks about PuTTY, but I thought it it might be worthwhile to try on your Java socket. 答案是关于PuTTY的,但我认为尝试使用Java套接字可能是值得的。 It's certainly a low hanging fruit to try. 尝试它当然是一个低悬的果实。 As such, try adding via calling connectionSocket.setKeepAlive(true); 因此,尝试通过调用connectionSocket.setKeepAlive(true); just after the Socket connectionSocket = serverSocket.accept(); 就在Socket connectionSocket = serverSocket.accept(); line. 线。

I tried to run your code in my pc (not in Android) and it work good with a simply call from browser to `localhost:8080'. 我试图在我的电脑上运行你的代码(不是在Android中),只需从浏览器调用“localhost:8080”即可。

I think you can do the same inside your device just to know if it's a client problem. 我想你可以在你的设备中做同样的事情,只是为了知道它是否是一个客户端问题。

I edited this two lines to avoid long waiting: 我编辑了这两行以避免长时间等待:

byte[] contentBytes = new byte[10];
    for (int i = 0; i < 10; i++) {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 软件导致连接异常终止:写入DataOutputStream时套接字写入错误 - Software caused connection abort: socket write error while writing to DataOutputStream Java错误 - 软件导致连接中止:recv失败 - Java error - Software caused connection abort: recv failed Java SocketException:软件导致连接中止 - Java SocketException: Software caused connection abort 软件导致连接中止:套接字写入错误 - Software caused connection abort: socket write error 在FTP中存储ObjectOutputStream导致java.net.SocketException:软件导致连接中止:套接字写入错误 - Store ObjectOutputStream in FTP causes java.net.SocketException: Software caused connection abort: socket write error java.net.SocketException:软件导致连接中止:重新提交请求时套接字写入错误 - java.net.SocketException: Software caused connection abort: socket write error when resubmitting the request BufferedReader.readLine()给出错误java.net.SocketException:软件导致连接中止:recv失败 - BufferedReader.readLine() gives error java.net.SocketException: Software caused connection abort: recv failed 通过串行端口java.net.SocketException的通信:软件导致连接中止:套接字写入错误 - Communication through serial port, java.net.SocketException: Software caused connection abort: socket write error jvisualvm:软件导致连接中止:套接字写入错误 - jvisualvm: Software caused connection abort: socket write error “软件导致连接中止:套接字写入错误”的官方原因 - Official reasons for "Software caused connection abort: socket write error"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM