如何让服务器“打开”,以便它可以持续发送和接收对象而不会崩溃?基本上,我想在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:~$
答案 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
,这很重要。从好的方面来说,它不会崩溃。