提问人:moto 提问时间:4/3/2020 更新时间:4/3/2020 访问量:139
while循环中的ObjectInputStream
ObjectInputStream within a while loop
问:
我有一个 java 项目,其中我必须有一个客户端和一个服务器。客户端将一个对象发送到服务器,服务器将其存储在向量中,基本上,以及其他任务。我的问题是我在运行时不断收到 EOF 异常。 这是我的服务器代码:
import java.net.*;
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
public class Server extends JFrame {
//Attributes
private Vector<Sales> allSales;
private int counter;
//Constructor
public Server() {
counter = 0;
setLayout(new BorderLayout());
allSales = new Vector<Sales>();
try {
InetAddress inetAddress = InetAddress.getLocalHost();
JLabel ip = new JLabel("IP Address of server: " + inetAddress.getHostAddress());
add(ip, BorderLayout.NORTH);
}
catch(UnknownHostException uhe) {
uhe.printStackTrace();
}
JButton jbWrite = new JButton("Write to CSV");
add(jbWrite, BorderLayout.SOUTH);
ActionListener writeListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
writeFilesToCSV();
}
};
//Window Listener that writes final files to csv on exit
addWindowListener(new WindowAdapter() {
public void actionPerformed(ActionEvent ae) {
writeFilesToCSV();
System.exit(0);
}
});
//Finalize GUI
setTitle("Server");
setSize(400,400);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//Internet stuff
try {
ServerSocket ss = new ServerSocket(16789);
Socket cs = null;
while(true) {
cs = ss.accept();
ThreadServer ths = new ThreadServer(cs);
ths.start();
}
}
catch(BindException be) {
System.out.println("Server already running");
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
//ThreadServer class
class ThreadServer extends Thread {
Socket cs;
public ThreadServer(Socket _cs) {
cs = _cs;
}
public void run() {
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
ois = new ObjectInputStream(new FileInputStream("file.dat"));
oos = new ObjectOutputStream(new FileOutputStream("file.dat"));
}
catch(IOException ioe) {ioe.printStackTrace(); }
while (true) {
try {
Object inOB = ois.readObject();
if(inOB instanceof String) {
String command = (String)inOB;
if(command.equalsIgnoreCase("count")) {
oos.writeObject(counter);
oos.flush();
}
if(command.equalsIgnoreCase("exit")) {
cs.close();
break;
}
}
else if(inOB instanceof Sales) {
synchronized(this) {
Sales saleToRecord = (Sales)inOB;
allSales.add(saleToRecord);
counter++;
}
}
}
catch(EOFException eofe) {
eofe.printStackTrace();
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
}
//Other Methods
public void writeFilesToCSV() {
synchronized(this) {
try {
File outFile = new File("Sales.csv");
FileWriter writer = new FileWriter(outFile, true);
for(Sales s : allSales) {
writer.write(s.getName() + "," + s.getNum() + "," + s.getItemNum() +"\n");
writer.flush();
}
allSales.clear();
writer.close();
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
//Main
public static void main(String[] args) {
new Server();
}
}
所以我知道错误发生在线程的语句上。我有run()
while(true) {
Object inOB = ois.readObject();
.....
}
这显然是抛出 EOF 异常,因为它正在尝试读取一个没有信息的文件,file.dat。该文件是客户端在将信息输入 GUI 时发送信息的地方。我试图弄清楚如何让代码等待对象发送,然后执行,或者我想只是不会产生无限数量的错误。
客户端代码(如果需要)
import java.net.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Client extends JFrame {
//Attributes
private JTextField jtfSP;
private JTextField jtfCN;
private JTextField jtfIN;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Sales outOB;
private Socket s;
//Constructors
public Client() {
//Create GUI for sales
//It should have a box to record Sales persons name, customer number, and item number of object sold
setLayout(new BorderLayout());
JPanel jpCenter = new JPanel();
GridLayout grid = new GridLayout(3,2);
jpCenter.setLayout(grid);
JLabel sp = new JLabel("Salesperson:"); //JLabel salesperson
jpCenter.add(sp);
jtfSP = new JTextField(); //text field salesperson
jpCenter.add(jtfSP);
JLabel cn = new JLabel("Customer number:"); //label cust num
jpCenter.add(cn);
jtfCN = new JTextField(); //text field cust num
jpCenter.add(jtfCN);
JLabel in = new JLabel("Item number:"); //label item num
jpCenter.add(in);
jtfIN = new JTextField(); //text field item num
jpCenter.add(jtfIN);
add(jpCenter, BorderLayout.CENTER);
//Record, Count, Exit Buttons
JPanel jpSouth = new JPanel();
GridLayout southGrid = new GridLayout(1,3);
jpSouth.setLayout(southGrid);
JButton jbRec = new JButton("RECORD");
jpSouth.add(jbRec);
JButton jbCount = new JButton("COUNT");
jpSouth.add(jbCount);
JButton jbExit = new JButton("EXIT");
jpSouth.add(jbExit);
add(jpSouth, BorderLayout.SOUTH);
//Create objectinput and output streams
try {
ois = new ObjectInputStream(new FileInputStream("file.dat"));
oos = new ObjectOutputStream(new FileOutputStream("file.dat"));
}
catch(IOException ioe) {ioe.printStackTrace(); }
//ActionListeners
/*
*recordListener
Listens if the record button is clicked
If it is, it sends record command to server
creates sale object
writes object to output
*/
ActionListener recordListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
//Sends object info
try {
String salesName = jtfSP.getText();
String custNum = jtfCN.getText();
String itemNum = jtfIN.getText();
outOB = new Sales(salesName, custNum, itemNum);
oos.writeObject(outOB);
oos.flush();
//Clear fields
jtfSP.setText(null);
jtfCN.setText(null);
jtfIN.setText(null);
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
};
jbRec.addActionListener(recordListener);
/*
* Count Listener
Listens to see if count button is clicked
If it does, it sounds count command to server
Server returns with amount of objects wrote
*/
ActionListener countListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
//Returns count of records
try {
int count;
oos.writeObject(new String("count"));
oos.flush();
count = (int)ois.readObject();
JOptionPane.showMessageDialog(null, "Count: " + count); //displays count
}
catch(IOException ioe) {
ioe.printStackTrace();
}
catch(ClassNotFoundException cnfe) { cnfe.printStackTrace(); }
}
};
jbCount.addActionListener(countListener);
/*
* exitListener
Listens to see if exit button is clicked
If it is it sends exit command to server
Shuts down exisiting writer
Exits program
*/
ActionListener exitListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
//Exits
try {
oos.writeObject(new String("exit"));
oos.flush();
ois.close();
oos.close();
System.exit(0);
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
};
jbExit.addActionListener(exitListener);
//Final Steps for gui
setTitle("Sales");
setSize(400,200);
setLocationRelativeTo(null);
//Does same task as exit button, but for the X button/ red dot on mac
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
try {
oos.writeObject(new String("exit"));
oos.flush();
ois.close();
oos.close();
System.exit(0);
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
});
setVisible(true);
//Connects to server
try {
s = new Socket("localhost", 16789);
}
catch(IOException ioe) {
String message = "Server has shut down or can not be connected to. No more orders will be accepted, the program will exit.";
JOptionPane.showMessageDialog(null, message);
System.exit(0);
}
}
//Other Methods
//Main
public static void main(String[] args) {
new Client();
}
}
答: 暂无答案
评论
actionPerformed()
WindowAdapter
readObject()
等待对象发送。这是一种阻塞方法。但是当你抓住时,你需要打破阅读循环。否则你只会继续得到它。没有真正的需要记录它。EOFException