java - 为什么服务器没有收到客户端发送的对象?

标签 java sockets client-server objectinputstream objectoutputstream

如何处理 ObjectOutputStreamObjectInputStream 以便 Server 实例正确记录接收到的 Object。目前,它永远不会走得那么远。每次客户端运行时,服务器都会“等待数据”,但似乎从未真正收到数据。

服务器:

package net.bounceme.dur.driver;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server {

    private static final Logger log = Logger.getLogger(Server.class.getName());
    private final RecordQueue recordsQueue = new RecordQueue();

    public static void main(String[] args) {
        Properties props = PropertiesReader.getProps();
        int portNumber = Integer.parseInt(props.getProperty("port"));

        while (true) {
            try {
                new Server().inOut(portNumber);
            } catch (java.net.SocketException se) {
                Logger.getLogger(Server.class.getName()).log(Level.FINE, "spammy", se);
            } catch (IOException ioe) {
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ioe);
            } catch (ClassNotFoundException cnf) {
                Logger.getLogger(Server.class.getName()).log(Level.INFO, null, cnf);
            }
        }
    }


    public void inOut(int portNumber) throws IOException, ClassNotFoundException {
        ServerSocket serverSocket = new ServerSocket(portNumber);
        Socket socket = serverSocket.accept();
        ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
        log.info("...connected...waiting for data...");
        MyRecord recordFromClient = (MyRecord) objectInputStream.readObject();
        objectOutputStream.writeObject(recordFromClient);
        objectOutputStream.flush();
        objectInputStream.close();
        objectOutputStream.close();
        log.info(recordFromClient.toString());//never logs
        System.out.println("never gets here");
    }
}

每次客户端运行时,服务器都会等待数据,但至少根据下面的输出,永远不会收到数据。

thufir@dur:~$ 
thufir@dur:~$ java -jar NetBeansProjects/Server/dist/Server.jar 
Jun 29, 2014 9:28:45 PM net.bounceme.dur.driver.Server inOut
INFO: ...connected...waiting for data...
Jun 29, 2014 9:28:46 PM net.bounceme.dur.driver.Server inOut
INFO: ...connected...waiting for data...

客户端代码:

package net.bounceme.dur.driver;

import java.net.*;
import java.io.*;
import java.util.Properties;
import java.util.logging.Logger;

public class Client {

    private static final Logger log = Logger.getLogger(Client.class.getName());

    public void put(String server, int portNumber, Socket socket, ObjectOutputStream objectOutputStream) throws IOException, ClassNotFoundException {
        socket = new Socket(server, portNumber);
        objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
        MyRecord record = new MyRecord(1, "foo");
        objectOutputStream.writeObject(record);
        objectOutputStream.flush();
        objectOutputStream.close();
    }

    public static void main(String args[]) throws IOException, ClassNotFoundException {
        Properties props = PropertiesReader.getProps();
        int portNumber = Integer.parseInt(props.getProperty("port"));
        String server = (props.getProperty("server"));
        Socket socket = null;
        ObjectOutputStream objectOutputStream = null;
        ObjectInputStream objectInputStream = null;
        new Client().put(server, portNumber, socket, objectOutputStream);
    }
}

最佳答案

客户端和服务器不仅必须在如何发送数据方面达成一致,而且还必须在何时关闭套接字方面达成一致。单方面关闭套接字将关闭连接并阻止接收甚至已经发送的数据。我认为这就是这里发生的事情。

客户端代码:

    objectOutputStream.writeObject(record);
    objectOutputStream.flush();
    objectOutputStream.close();

这是不间断执行的,因此一旦在线上发送了最后一个字节,套接字就会关闭。因此,服务器的回复无法发送。

服务器代码:

    MyRecord recordFromClient = (MyRecord) objectInputStream.readObject();
    objectOutputStream.writeObject(recordFromClient);

显然,接收发生得比发送晚一点,因此服务器会阻塞。

保持套接字从双方打开,直到客户端收到;然后他可以关闭套接字。当尝试再次读取时,服务器应该看到文件结尾,并可以相应地关闭。 (当然,更复杂的握手是可能的。)

稍后

为了证实这一点,只需添加 Thread.sleep(2000);在客户端的刷新和关闭之间 - 服务器确实会“到达这里”。

关于java - 为什么服务器没有收到客户端发送的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24482968/

相关文章:

ruby-on-rails - 具有远程 Rails 服务器的 BackBone 客户端

java - 访问 DefaultListModel 的索引时出现空指针异常

java - 在输入中包含条件

java - 在嵌套列表中搜索项目

java - 服务器不解码数据包

路由器后面的 Python 客户端/服务器

Java 小程序 Jbutton 错误

java - 如何使用异步套接字?

c - 套接字连接结束,操作正在非阻塞套接字上进行

java - Tomcat 8 Docx4j 应用问题