【问题标题】:why doesn't the server receive the object sent from the client?为什么服务器收不到客户端发送的对象?
【发布时间】:2014-08-20 09:39:05
【问题描述】:

如何处理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);
    }
}

【问题讨论】:

  • 你为什么将 null 值传递给 put() ,然后再不读取?
  • 我可能有一个无限循环来进行一些迭代,但还不确定。

标签: java sockets client-server objectinputstream objectoutputstream


【解决方案1】:

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

客户端代码:

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

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

服务器代码:

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

显然,接收比发送稍晚,因此服务器阻塞。

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

稍后

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

【讨论】:

  • 谢谢。我不喜欢这样,似乎在我看来,当刷新/关闭 if 对象从未成功时,客户端应该抛出错误。或者也许这就是套接字的样子?
  • 套接字只是一个通信端点。较低的协议级别决定来回发送什么,以及何时以及如何发送。经常需要超时来限制阻塞 i/o 操作中的等待。与默认设置相比,可以设置范围广泛的参数。
猜你喜欢
  • 2017-07-14
  • 2013-11-16
  • 1970-01-01
  • 2014-10-08
  • 2021-12-04
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多