【问题标题】:how to keep a "Hello World" type server running如何保持“Hello World”类型的服务器运行
【发布时间】:2014-06-30 01:49:32
【问题描述】:

如何保持服务器“打开”,以便它可以持续发送和接收对象而不会崩溃?基本上,我想在 readRecord 方法周围放置一个无限循环,以便它无限期地运行。

服务器:

package net.bounceme.dur.driver;

import java.net.*;
import java.io.*;
import java.util.Properties;
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) throws IOException {
        Properties props = PropertiesReader.getProps();
        int portNumber = Integer.parseInt(props.getProperty("port"));
        new Server().readRecord(portNumber);
    }

    public void readRecord(int portNumber) throws IOException {
        ServerSocket serverSocket = new ServerSocket(portNumber);
        Socket socket = serverSocket.accept();
        ObjectOutputStream objectOutputStream = null;
        MyRecord recordFromClient = null;
        ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
        objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
        while (true) {
            try {
                recordFromClient = (MyRecord) objectInputStream.readObject();
            } catch (ClassNotFoundException e) {
                System.out.println(e);
            }
            objectOutputStream.writeObject(recordFromClient);
        }
    }
}  

客户:

package net.bounceme.dur.driver;

import java.net.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class Client {

    private List<MyRecord> iterate() {
        MyRecord myRecord = null;
        List<MyRecord> records = new ArrayList<>();
        for (int i = 0; i < 9; i++) {
            myRecord = new MyRecord(i, "foo");
            records.add(myRecord);
        }
        return records;
    }

    public void simple(String server, int portNumber) throws IOException, ClassNotFoundException {
        Socket s = new Socket(server, portNumber);
        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
        ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
        List<MyRecord> records = iterate();
        for (MyRecord record : records) {
            oos.writeObject(record);
        }
        oos.flush();
        Object received = ois.readObject();
        System.out.println(received);
        oos.close();
        ois.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"));
        new Client().simple(server, portNumber);
    }
}

服务器输出:

thufir@dur:~$ 
thufir@dur:~$ java -jar NetBeansProjects/Server/dist/Server.jar 
Exception in thread "main" java.net.SocketException: Broken pipe
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1876)
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1785)
    at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1285)
    at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1230)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1426)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
    at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1576)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:350)
    at net.bounceme.dur.driver.Server.readRecord(Server.java:32)
    at net.bounceme.dur.driver.Server.main(Server.java:16)
thufir@dur:~$ 

客户端输出:

thufir@dur:~$ 
thufir@dur:~$ java -jar NetBeansProjects/Client/dist/Client.jar 
value=0, id='foo
thufir@dur:~$ 

【问题讨论】:

    标签: java sockets io stream client-server


    【解决方案1】:

    好的,您的问题是,您的服务器一次只能读取和处理一个对象。因此,当您的客户端尝试发送所有这些 MyRecord 对象时,服务器会读取一个,然后尝试将其发送回给您,问题是,您仍在尝试发送其他 MyRecord 对象,而服务器正在尝试发送您第一个 MyRecord 对象。客户端/服务器连接就像一场网球比赛。一个人必须将球传给另一名球员,然后另一个人必须将球击回。你们不能都击球而你们都没有接球。

    所以,

        for (MyRecord record : records) {
            oos.writeObject(record);
        }
        oos.flush();
        Object received = ois.readObject();
        System.out.println(received);
    

    你应该把

        oos.flush();
        Object received = ois.readObject();
        System.out.println(received);
    

    for() 循环内部,这样每个MyRecord 对象都会被发送到服务器,由服务器读取,由服务器发送回客户端,然后由客户端读取。

    最终结果:

        for (MyRecord record : records) {
            oos.writeObject(record);
            oos.flush();
            Object received = ois.readObject();
            System.out.println(received);
        }
    

    【讨论】:

    • 经过反思,一次一个对象就可以了。我只想记录服务器在这个时刻收到的对象。我更新了我的答案。
    【解决方案2】:

    查看更改(我编辑了一些代码以在我的机器上运行,因此请适当地进行更改)

    import java.net.*;
    import java.io.*;
    import java.util.Properties;
    import java.util.logging.Logger; 
    import java.util.ArrayList;
    import java.util.List;
    class MyRecord implements java.io.Serializable
    {
    int x;
    String y;
    MyRecord(int a,String b)
    {
    x=a;
    y=b;
    }
    }
    
    class Server {
    
    private static final Logger log = Logger.getLogger(Server.class.getName());
    //private final RecordQueue recordsQueue = new RecordQueue();
    
    public static void main(String[] args) throws IOException {
        //Properties props = PropertiesReader.getProps();
        //int portNumber = Integer.parseInt(props.getProperty("port"));
        new Server().readRecord(2*1000);
    }
    
    public void readRecord(int portNumber) throws IOException {
        ServerSocket serverSocket = new ServerSocket(portNumber);
        Socket socket = serverSocket.accept();
        ObjectOutputStream objectOutputStream = null;
        MyRecord recordFromClient = null;
        ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
        objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
        while (true) {
            try {
                recordFromClient = (MyRecord) objectInputStream.readObject();
                if(recordFromClient.x==-1) {break;}
            } catch (ClassNotFoundException e) {
                System.out.println(e);
            }
            objectOutputStream.writeObject(recordFromClient);
            objectOutputStream.flush();
        }
    }
    }  
    
    class Client {
    
    private List<MyRecord> iterate() {
        MyRecord myRecord = null;
        List<MyRecord> records = new ArrayList<>();
        for (int i = 0; i < 9; i++) {
            myRecord = new MyRecord(i, "foo");
            records.add(myRecord);
        }
        return records;
    }
    
    public void simple(String server, int portNumber) throws IOException, ClassNotFoundException {
        Socket s = new Socket(server, portNumber);
        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
        ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
        List<MyRecord> records = iterate();
        for (MyRecord record : records) {
            oos.writeObject(record);
        oos.flush();
        Object received = ois.readObject();
        System.out.println(received);
        }
        MyRecord record= new MyRecord(-1,"end");
        oos.writeObject(record);
        oos.flush();
        oos.close();
        ois.close();
    }
    
    public static void main(String args[]) throws IOException, ClassNotFoundException {
        //Properties props = PropertiesReader.getProps();
        //int portNumber = Integer.parseInt(props.getProperty("port"));
        String server = "localhost";
        new Client().simple(server, 2000);
    }
    }
    

    【讨论】:

    • 你为什么使用break?我更新了我的答案,但仍然无法记录服务器接收到的对象。
    • break 因为当客户端完成发送记录时,服务器继续读取期望(不知道客户端已经发送了它必须发送的所有记录)更多记录,所以如果你评论该语句,你会得到一个 EOFException。这样做是为了表明客户端已完成发送对象
    【解决方案3】:

    这在一定程度上有效:

    package net.bounceme.dur.driver;
    
    //import stuff
    
    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 (IOException | ClassNotFoundException ex) {
                    Logger.getLogger(Server.class.getName()).log(Level.FINE, null, ex);
                }
            }
        }
    
        private List<MyRecord> dummyRecords() {
            MyRecord record = null;
            List<MyRecord> records = new ArrayList<>();
            for (int i = 0; i < 9; i++) {
                record = new MyRecord(i, "foo");
                records.add(record);
                log.info(record.toString());
            }
            return records;
        }
    
        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");
        }
    }
    

    除了它从不记录recordFromClient,这很重要。从好的方面来说,它不会崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      • 2013-01-26
      • 1970-01-01
      • 1970-01-01
      • 2010-11-25
      • 1970-01-01
      相关资源
      最近更新 更多