Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 套接字在能够读取ObjectInputStream(BufferedInputStream(Socket.getInputStream))之前关闭_Java_Sockets_Objectinputstream - Fatal编程技术网

Java 套接字在能够读取ObjectInputStream(BufferedInputStream(Socket.getInputStream))之前关闭

Java 套接字在能够读取ObjectInputStream(BufferedInputStream(Socket.getInputStream))之前关闭,java,sockets,objectinputstream,Java,Sockets,Objectinputstream,我已经编写了一个小的客户机/服务器程序,它已经运行了一次,但是在添加线程和一些实际的输入数据之后,我总是在能够读取对象(字符串)之前得到一个闭合的套接字。程序始终从ProcessDataThread中的函数handleConnection打印“客户端已关闭连接!” 客户端代码: synchronized private static void sendToServer(){ Socket clientSocket = null; BufferedOutputStream

我已经编写了一个小的客户机/服务器程序,它已经运行了一次,但是在添加线程和一些实际的输入数据之后,我总是在能够读取对象(字符串)之前得到一个闭合的套接字。程序始终从ProcessDataThread中的函数handleConnection打印“客户端已关闭连接!”

客户端代码:

synchronized private static void sendToServer(){
        Socket clientSocket = null;
    BufferedOutputStream socketOut = null;
        ObjectOutputStream out = null;
    try{ 

        String xmlToSend = "<startTag>\n<someOtherTag id=\"5555\">\n12345\n</someOtherTag>\n</startTag>\n";

        Log.d(TAG, "Trying to send the following to the Server:" + xmlToSend);

        //TODO load these from file
        clientSocket = new Socket( "10.0.2.2", 7777);
        socketOut = new BufferedOutputStream(clientSocket.getOutputStream());
        out = new ObjectOutputStream(socketOut);
        out.writeObject(xmlToSend);
        out.flush();

    }catch(Exception ex){
        Log.e(TAG, "Could not write File to Server.", ex);
    }
    finally{
        try{
            if(clientSocket != null){
                clientSocket.close();
            }
            if(out != null){
                out.close();
            }
        }catch(IOException ex){
            Log.e(TAG, "Could not close Socket.");
        }
    }
}
public void run()
{
    try {
        ServerSocket server = new ServerSocket(port);
        //Only block for 10 Seconds and try again
        server.setSoTimeout(10000);
        while(!server.isClosed() && !stopped){
            //Run
             Socket client = null;
              try
              {
                client = server.accept();
                System.out.println("Accepted ClientConnection from " + client.getRemoteSocketAddress());
                new ProcessDataThread(client).start();
              }
              catch( SocketTimeoutException tx){
                  //nothing
              }
              catch ( IOException e ) {
                e.printStackTrace();
              }
              finally {
                if ( client != null )
                  try { client.close(); } catch ( IOException e ) { e.printStackTrace(); }
              }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}
public class ProcessDataThread extends Thread {

Socket client;

public ProcessDataThread(Socket sock) {
    // xmlToProcess = xmlString;
    this.client = sock;
}

private String handleConnection() {

    BufferedInputStream socketIn = null;
    ObjectInputStream in = null;
    String xmlToProcess = null;
    try {
        if(!client.isClosed()){
            System.out.println("Trying to read from Stream;");
            socketIn = new BufferedInputStream(client.getInputStream());
            in = new ObjectInputStream(socketIn);

            Object xmlString = in.readObject();
            System.out.println("Read some Object from Stream:" + xmlString.toString());
            if (xmlString instanceof String) {
                xmlToProcess = (String) xmlString;
                System.out.println("Received the following XML:\n" + xmlToProcess);
            }
        }else{
            System.out.println("Client has already closed Connection!");
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (EOFException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (socketIn != null) {
                socketIn.close();
            }
            if(client != null){
                client.close();
            }
        } catch (IOException ioex) {
            ioex.printStackTrace();
        }
    }
    return xmlToProcess;
}

@Override
public void run() {

    String xmlToProcess = handleConnection();

    if (xmlToProcess == null || xmlToProcess.isEmpty()) {
        // Es konnte kein String vom Client gelesen werden.
        return;
    }

            System.out.println(xmlToProcess);
 }
}
ProcessDataThread:

synchronized private static void sendToServer(){
        Socket clientSocket = null;
    BufferedOutputStream socketOut = null;
        ObjectOutputStream out = null;
    try{ 

        String xmlToSend = "<startTag>\n<someOtherTag id=\"5555\">\n12345\n</someOtherTag>\n</startTag>\n";

        Log.d(TAG, "Trying to send the following to the Server:" + xmlToSend);

        //TODO load these from file
        clientSocket = new Socket( "10.0.2.2", 7777);
        socketOut = new BufferedOutputStream(clientSocket.getOutputStream());
        out = new ObjectOutputStream(socketOut);
        out.writeObject(xmlToSend);
        out.flush();

    }catch(Exception ex){
        Log.e(TAG, "Could not write File to Server.", ex);
    }
    finally{
        try{
            if(clientSocket != null){
                clientSocket.close();
            }
            if(out != null){
                out.close();
            }
        }catch(IOException ex){
            Log.e(TAG, "Could not close Socket.");
        }
    }
}
public void run()
{
    try {
        ServerSocket server = new ServerSocket(port);
        //Only block for 10 Seconds and try again
        server.setSoTimeout(10000);
        while(!server.isClosed() && !stopped){
            //Run
             Socket client = null;
              try
              {
                client = server.accept();
                System.out.println("Accepted ClientConnection from " + client.getRemoteSocketAddress());
                new ProcessDataThread(client).start();
              }
              catch( SocketTimeoutException tx){
                  //nothing
              }
              catch ( IOException e ) {
                e.printStackTrace();
              }
              finally {
                if ( client != null )
                  try { client.close(); } catch ( IOException e ) { e.printStackTrace(); }
              }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}
public class ProcessDataThread extends Thread {

Socket client;

public ProcessDataThread(Socket sock) {
    // xmlToProcess = xmlString;
    this.client = sock;
}

private String handleConnection() {

    BufferedInputStream socketIn = null;
    ObjectInputStream in = null;
    String xmlToProcess = null;
    try {
        if(!client.isClosed()){
            System.out.println("Trying to read from Stream;");
            socketIn = new BufferedInputStream(client.getInputStream());
            in = new ObjectInputStream(socketIn);

            Object xmlString = in.readObject();
            System.out.println("Read some Object from Stream:" + xmlString.toString());
            if (xmlString instanceof String) {
                xmlToProcess = (String) xmlString;
                System.out.println("Received the following XML:\n" + xmlToProcess);
            }
        }else{
            System.out.println("Client has already closed Connection!");
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (EOFException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (socketIn != null) {
                socketIn.close();
            }
            if(client != null){
                client.close();
            }
        } catch (IOException ioex) {
            ioex.printStackTrace();
        }
    }
    return xmlToProcess;
}

@Override
public void run() {

    String xmlToProcess = handleConnection();

    if (xmlToProcess == null || xmlToProcess.isEmpty()) {
        // Es konnte kein String vom Client gelesen werden.
        return;
    }

            System.out.println(xmlToProcess);
 }
}
我对jboi的建议做了一些修改。这就是我现在得到的。错误保持不变。我甚至无法读取服务器中的流,因为
client.getClosed()
这永远是真的

在客户端代码中:

在服务器代码中


不能在同一套接字上使用缓冲输入流和其他类型的流。缓冲流将从另一个流窃取数据。下定决心吧。
ObjectInputStream
将完成您需要的所有操作。就用这个吧


编辑重新编辑,“套接字关闭”表示您关闭了套接字,然后继续使用它。

很可能是在服务器能够读取数据之前,您的客户端已在finally块中关闭了套接字

在您的客户端最终块中,您应该使用
socket.shutdownOutput
,然后在客户端上读取所有传入数据,直到EOF,然后关闭套接字

在服务器上,您读取到EOF,然后发送一个对象作为确认,例如消息中的字节数。您还可以使用socket.shutdownOutput()结束发送,就像您在客户端所做的那样。这会在数据末尾再次放置EOF。此EOF由客户端接收,它将最终关闭套接字。

好吧,现在我觉得自己很愚蠢。 我自己关闭了服务器代码中的套接字。 接受连接后,在finally块内执行以下操作:

试试看{
client.close();
}捕获(IOE异常){
e、 printStackTrace();
}
出现这个finally块的原因是因为我以前没有使用线程,所以ReceiverThread也处理连接,因此在使用它之后关闭套接字。
然后我将代码移动到新线程,忘记删除finally块

问题似乎是客户端和服务器无法识别彼此的状态:

  • 正在向服务器发送数据的客户端,服务器已关闭该连接
  • 服务器向客户端发送/读取数据,客户端已关闭连接
  • 如果两者都无法相互协调,解决方案可能是建立一个适当的状态机。如果您搜索(客户端和服务器状态机),Google中的一些示例为您的应用程序提供了数学上确定的状态机示例:希望此评论有帮助


    因此,从解决方案的角度来研究这个问题并没有用,可能会开始使用协议,如:telnet等。

    谢谢您的快速回复。我从一些教程中得到了代码,我再也找不到了。但它已经成功过一次。我想有人告诉我,如果没有系统缓冲,BufferedInputStream会管理套接字的缓冲区。但是为了尝试你的技巧,你说的“组成你的种类”是什么意思?我现在尝试了你的技巧,如果我没有弄错的话,我使用了`clientSocket=newsocket(“10.0.2.2”,7777);setTcpNoDelay(true);out=newObjectOutputStream(clientSocket.getOutputStream());out.writeObject(xmlToSend);out.flush();`但它不起作用,我遇到了和前面提到的一样的问题。还有一篇文章,其中ObjectInputStream和BufferedInputStream被连接在一起使用:@asgaroth我在你的链接中没有看到任何“连接”的内容。我所能看到的只是重复我在这里给你的建议。谢谢你的回复!你能举个例子说明如何阅读到EOF吗?我必须在客户机中创建InputStream吗?因为通常我只发送而不接收任何东西。我想你的回答可能是正确的。我就是不知道该怎么做。我用你的建议更新了我的测试问题,但仍然不起作用@jboiI接受了你的答案,因为这是检查是否所有事情都完成的好方法。@asgaroth很抱歉,我不能给出代码示例。我不在笔记本电脑旁,只有一部智能手机可以写一些文字。远离笔记本电脑==假期:-)@asgaroth:我在下面链接的答案中找到了一个代码片段。你应该能够复制出结束顺序。