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

时间:2014-06-30 04:34:07

标签: 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);
    }
}

1 个答案:

答案 0 :(得分:2)

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

客户代码:

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

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

服务器代码:

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

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

在客户收到之前,从两侧打开插座;然后他可以关闭插座。尝试再次读取时,服务器应该看到文件结尾,并且可以相应地关闭。 (当然,可以进行更精细的握手。)

<强>后来

要进行corroberate,只需添加一个Thread.sleep(2000);在客户的刷新和关闭之间 - 服务器确实会“到达这里”。