如何保持“Hello World”类型的服务器运行

时间:2014-06-30 01:49:32

标签: java sockets io stream client-server

如何让服务器“打开”,以便它可以持续发送和接收对象而不会崩溃?基本上,我想在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:~$ 

3 个答案:

答案 0 :(得分:1)

好的问题是,您的服务器一次只能读取和处理一个对象。因此,当您的客户端尝试发送所有这些MyRecord对象时,服务器会读取一个,然后尝试将其发送给您,问题是,当服务器尝试发送给您时,您仍在尝试发送其他MyRecord对象FIRST 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);
    }

答案 1 :(得分:1)

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

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);
}
}

答案 2 :(得分:0)

这在一定程度上起作用:

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,这很重要。从好的方面来说,它不会崩溃。