У меня есть проект 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();
}
}