- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个消息传递应用程序,并且我能够发送消息(显示为服务器客户端正确显示消息)但随后将我的客户端踢出服务器。服务器打印以下错误:
java.io.EOFException at java.io.ObjectInputStream$BlockDataInputStream.peekByte(UnknownSource) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at com.liftedstarfish.lifte.gpschat0_2.Server$ClientThread.run(Server.java:243)
我的服务器类:
public class Server {
// a unique ID for each connection
private static int uniqueId;
// an ArrayList to keep the list of the Client
private ArrayList<ClientThread> al;
// if I am in a GUI
private ServerGUI sg;
// to display time
private SimpleDateFormat sdf;
// the port number to listen for connection
private int port;
// the boolean that will be turned of to stop the server
private boolean keepGoing;
private String name;
/*
* server constructor that receive the port to listen to for connection as parameter
* in console
*/
public Server(int port, String name) {
this(port, name, null);
}
public Server(int port, String name, ServerGUI sg) {
// GUI or not
this.sg = sg;
// the port
this.port = port;
this.name = name;
// to display hh:mm:ss
sdf = new SimpleDateFormat("HH:mm:ss");
// ArrayList for the Client list
al = new ArrayList<ClientThread>();
}
public void start() {
keepGoing = true;
/* create socket server and wait for connection requests */
try
{
// the socket used by the server
ServerSocket serverSocket = new ServerSocket(port);
// infinite loop to wait for connections
while(keepGoing)
{
// format message saying we are waiting
display("Server waiting for Clients on " + name + ".");
Socket socket = serverSocket.accept(); // accept connection
// if I was asked to stop
if(!keepGoing)
break;
ClientThread t = new ClientThread(socket); // make a thread of it
al.add(t); // save it in the ArrayList
t.start();
}
// I was asked to stop
try {
serverSocket.close();
for(int i = 0; i < al.size(); ++i) {
ClientThread tc = al.get(i);
try {
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
}
catch(IOException ioE) {
// not much I can do
}
}
}
catch(Exception e) {
display("Exception closing the server and clients: " + e);
}
}
// something went bad
catch (IOException e) {
String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
display(msg);
}
}
/*
* For the GUI to stop the server
*/
protected void stop() {
keepGoing = false;
// connect to myself as Client to exit statement
// Socket socket = serverSocket.accept();
try {
new Socket("localhost", port);
}
catch(Exception e) {
// nothing I can really do
}
}
/*
* Display an event (not a message) to the console or the GUI
*/
private void display(String msg) {
String time = sdf.format(new Date()) + " " + msg;
if(sg == null)
System.out.println(time);
else
sg.appendEvent(time + "\n");
}
/*
* to broadcast a message to all Clients
*/
private synchronized void broadcast(String message) {
// add HH:mm:ss and \n to the message
String time = sdf.format(new Date());
String messageLf = time + " " + message + "\n";
// display message on console or GUI
if(sg == null)
System.out.print(messageLf);
else
sg.appendRoom(messageLf); // append in the room window
// we loop in reverse order in case we would have to remove a Client
// because it has disconnected
for(int i = al.size(); --i >= 0;) {
ClientThread ct = al.get(i);
// try to write to the Client if it fails remove it from the list
if(!ct.writeMsg(messageLf)) {
al.remove(i);
display("Disconnected Client " + ct.username + " removed from list.");
}
}
}
// for a client who logoff using the LOGOUT message
synchronized void remove(int id) {
// scan the array list until we found the Id
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
// found it
if(ct.id == id) {
al.remove(i);
return;
}
}
}
/*
* To run as a console application just open a console window and:
* > java Server
* > java Server portNumber
* If the port number is not specified 1500 is used
*/
public static void main(String[] args) {
// start server on port 1500 unless a PortNumber is specified
int portNumber = 1500;
String serverName = "";
switch(args.length) {
case 1:
try {
portNumber = Integer.parseInt(args[0]);
}
catch(Exception e) {
System.out.println("Invalid port number.");
System.out.println("Usage is: > java Server [portNumber]");
return;
}
case 0:
break;
default:
System.out.println("Usage is: > java Server [portNumber]");
return;
}
// create a server object and start it
Server server = new Server(portNumber, serverName);
server.start();
}
public String getName()
{
return this.name;
}
/** One instance of this thread will run for each client */
class ClientThread extends Thread {
// the socket where to listen/talk
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
// my unique id (easier for deconnection)
int id;
// the Username of the Client
String username;
// the only type of message a will receive
ChatMessage cm;
// the date I connect
String date;
// Constructore
public ClientThread(Socket socket) {
// a unique id
id = ++uniqueId;
this.socket = socket;
/* Creating both Data Stream */
System.out.println("Thread trying to create Object Input/Output Streams");
try
{
// create output first
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
// read the username
username = (String) sInput.readObject();
display(username + " just connected.");
}
catch (IOException e) {
display("Exception creating new Input/output Streams: " + e);
return;
}
// have to catch ClassNotFoundException
// but I read a String, I am sure it will work
catch (ClassNotFoundException e) {
}
date = new Date().toString() + "\n";
}
// what will run forever
public void run() {
// to loop until LOGOUT
boolean keepGoing = true;
while(keepGoing) {
// read a String (which is an object)
try {
//Location of Error
>>>>>>>>>>>>>>>>>>>>cm = (ChatMessage) sInput.readObject();<<<<<<<<<<<<<<<<<
}
catch (IOException e) {
e.printStackTrace();
break;
}
catch(ClassNotFoundException e2) {
e2.printStackTrace();
break;
}
// the messaage part of the ChatMessage
String message = cm.getMessage();
// Switch on the type of message receive
switch(cm.getType()) {
case ChatMessage.MESSAGE:
broadcast(username + ": " + message);
break;
case ChatMessage.LOGOUT:
display(username + " disconnected with a LOGOUT message.");
keepGoing = false;
break;
case ChatMessage.WHOISIN:
writeMsg("List of the users connected at " + sdf.format(new Date()) + "\n");
// scan al the users connected
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
writeMsg((i+1) + ") " + ct.username + " since " + ct.date);
}
break;
case ChatMessage.ERROR:
broadcast(username + "> " + message);
break;
}
}
// remove myself from the arrayList containing the list of the
// connected Clients
remove(id);
close();
}
// try to close everything
private void close() {
// try to close the connection
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {};
try {
if(socket != null) socket.close();
}
catch (Exception e) {}
}
/*
* Write a String to the Client output stream
*/
private boolean writeMsg(String msg) {
// if Client is still connected send the message to it
if(!socket.isConnected()) {
close();
return false;
}
// write the message to the stream
try {
sOutput.writeObject(msg);
}
// if an error occurs, do not abort just inform the user
catch(IOException e) {
display("Error sending message to " + username);
display(e.toString());
}
return true;
}
}
}
聊天消息类:
public class ChatMessage extends AppCompatActivity implements Serializable {
protected static final long serialVersionUID = 1112122200L;
// The different types of message sent by the Client
// WHOISIN to receive the list of the users connected
// MESSAGE an ordinary message
// LOGOUT to disconnect from the Server
static final int WHOISIN = 0, MESSAGE = 1, LOGOUT = 2, ERROR = 3;
private int type;
private String message;
// constructor
public ChatMessage(int type, String message) {
this.type = type;
this.message = message;
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_message);
final TextView lblMessage = (TextView) findViewById(R.id.text_view_message);
if(type == MESSAGE)
lblMessage.setText(message);
}
// getters
public int getType() {
return type;
}
public String getMessage() {
return message;
}
}
最佳答案
来自 readObject 文档:
ClassNotFoundException - Class of a serialized object cannot be found.
InvalidClassException - Something is wrong with a class used by serialization.
StreamCorruptedException - Control information in the stream is inconsistent.
OptionalDataException - Primitive data was found in the stream instead of objects.
IOException - Any of the usual Input/Output related exceptions.
EOFException是IOException的一种,当到达文件末尾时抛出。尽管这不会抛出该特定错误,但它确实会抛出 IOException,这意味着它也可以抛出 EOFException。
因此在您的代码中,您只需添加:
while(sInput.available() > 0){// > 0 means there are bytes to read.
//Read
}
这(理论上)避免了 EOFException。参见 this供引用
关于java - 服务器端 EOFException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43429603/
我编写了以下客户端-服务器对来设置一个非常简化版本的 IPSec 连接(与加密相关)。 问题是,在第二次调用 readObject() 时,即: // Receive finished
我创建了一个 Talend 作业,它执行以下操作:从表 A 中读取记录 x。将记录 x + 1.000.000 写入表 A 中。这很有效,但在 310 条记录后失败。它显然与记录中的值无关。如果我将输
我正在使用iText将html转换为pdf,当我尝试注册fontProvider时,我得到EOFException,这里是相关代码: XMLWorkerFontProvider fontProvide
以下代码在反序列化期间抛出 EOFException [in line size = in.readInt();],我很困惑为什么会发生这种情况。 import java.io.IOException
我正在使用此代码读取 Java 中的文件 import java.io.*; public class IOReadDataStreams { public static void main(
我的目标是将远程服务器中的 200 个 .jpg 文件下载到我的 Android 手机(运行 jellybeans)。为了做到这一点,我在循环中运行下面的方法,并将不同的文件名分配给文件名参数。它运行
输出正确,但后面跟着一个 EOFException。我阅读了文档,但仍然不知道如何解决这个问题 try(ObjectInputStream ois = new ObjectInputStream(ne
我有一个通过套接字向主机发送数据的客户端。有时我会得到java.io.EOFException。 问题是:我如何知道是谁导致套接字关闭?由于远程主机关闭了套接字,该异常是否总是引发? 或者也可能是内部
这个问题已经有答案了: Java FileInputStream ObjectInputStream reaches end of file EOF (9 个回答) 已关闭 9 年前。 请看下面的代码
我尝试使用 this question's answer 来获得功能实现,但出现各种错误,现在出现 EOFException,并且在调试时,似乎文件未写入。 目标是从 URL 下载图像,将其保存到内部
我正在测试 ObjectInputStream 和 ObjectOutputStream 类 尝试在缓冲流对象中扭曲两者.. File file = new File("file.lel"); //A
我使用文件来缓冲它来显示流内容(因为它可能足够大以将其保存在 RAM 中)。我有两个线程:第一个线程从服务器下载文件并将其写入本地存储,第二个线程读取该文件并显示内容。 问题是,当第二个线程到达文件末
`INFO 11:44:29,874 Listening for thrift clients... ERROR 11:47:01,471 Exception in thread Thread[Rea
我在反序列化对象时遇到此异常: 控制台输出 sending request: GET_OBJS java.io.EOFException receiving response at java.io.O
我正在使用以下代码进行发布请求 public String executeHttpPost(String uri, String data) { HttpURLConnection conn
我正在通过加密的 ByteArrayOutputStream 将一个序列化和加密的对象写入数据库到一个大对象中。我可以检索这个大对象,但无法反序列化它。 这是我编写的代码: public void a
这个问题在这里已经有了答案: java.io.EOFException while writing and reading froma servlet (2 个答案) 关闭 10 年前。 当我尝试通
我正在尝试编写一个消息传递应用程序,并且我能够发送消息(显示为服务器客户端正确显示消息)但随后将我的客户端踢出服务器。服务器打印以下错误: java.io.EOFException at java.i
我有以下问题: 这段代码... try { fis = new FileInputStream(serializedKeyIndex); in = new Ob
我正在使用随机访问文件来编写一个使用 arrayList 存储的 raf。我不知道它是否可以完成,但我正在试一试,因为它是我创建此应用程序的最佳解决方案。 这是我遇到的运行时错误: Exception
我是一名优秀的程序员,十分优秀!