【发布时间】:2014-12-06 14:07:08
【问题描述】:
这是我在 Stack Overflow 上的第一篇文章,所以我希望我能以最低限度的体面做这件事。
我尝试使用 Java 套接字实现一个简单的解决方案,但遇到了异常。我肯定在滥用 API,但我不知道为什么以及在哪里。
客户端需要向服务器发送多个二进制消息,并且它(客户端)必须重用同一个套接字。
在服务器中,我创建了一个线程来做两件事:(1) 接受客户端请求,(2) 实例化一个新线程(运行 ClientWorker 实例)来处理客户端请求。
如果我只从客户端发送一条消息,一切正常。不过,当我尝试发送多条消息时,在第二条消息中出现以下异常:
java.io.StreamCorruptedException:无效类型代码:AC at java.io.ObjectInputStream.readObject0(未知来源)在 java.io.ObjectInputStream.readObject(Unknown Source) 在 simple.socketexample.ClientWorker.run(ClientWorker.java:26) 在 java.lang.Thread.run(未知来源)
异常发生在我的 ClienWorker 类中,在“Message message = (Message)in.readObject();”行中请注意,服务器始终成功接收到第一条消息。
以下类是我创建的一个简单示例的一部分,只是为了显示此错误。
第一类是Message:
package simple.socketexample;
import java.io.Serializable;
public class Message implements Serializable {
private static final long serialVersionUID = 4473470814745876900L;
private String text;
private int number;
public Message(String text, int number) {
super();
this.text = text;
this.number = number;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public String toString() {
return "Message [text=" + text + ", number=" + number + "]";
}
}
这是我的客户:
public class Client {
private final int SERVER_PORT = 3456;
private final String SERVER_HOST = "localhost";
private Socket serverSocket;
public void connect() throws IOException, UnknownHostException {
serverSocket = new Socket(SERVER_HOST, SERVER_PORT);
}
public void disconnect() throws IOException {
serverSocket.close();
}
public void sendMessage(Message message) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(serverSocket.getOutputStream());
out.writeObject(message);
out.flush();
out.reset();
}
}
服务器:
public class Server {
private final int SERVER_PORT = 3456;
public void start() throws IOException {
Thread acceptConnectionsThread = new Thread(new Runnable() {
public void run() {
// Instantiates the socket
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(SERVER_PORT);
} catch (IOException e) {
e.printStackTrace();
}
// Starts accepting client connections
while(true) {
Socket socketFromClient = null;
try {
socketFromClient = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
// Create a new "client dedicated thread"
ClientWorker clientWorker = new ClientWorker(socketFromClient);
Thread clientDedicatedThread = new Thread(clientWorker);
clientDedicatedThread.start();
}
}
});
acceptConnectionsThread.start();
}
}
我的客户工作者:
public class ClientWorker implements Runnable {
private Socket socketFromClient;
public ClientWorker(Socket socketFromClient) {
super();
this.socketFromClient = socketFromClient;
}
public void run() {
ObjectInputStream in = null;
try {
in = new ObjectInputStream(socketFromClient.getInputStream());
} catch (IOException e) {
e.printStackTrace();
return;
}
while(true) {
try {
Message message = (Message)in.readObject();
System.out.println(message);
} catch (ClassNotFoundException e) {
e.printStackTrace();
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
还有我用来测试这个的类: 包 simple.socketexample;
import java.io.IOException;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) throws Exception {
// Start the server in a new (background) thread
Thread serverInBackground = new Thread(new Runnable() {
public void run() {
Server server = new Server();
try {
server.start();
} catch (IOException e) {
e.printStackTrace();
}
}
});
serverInBackground.start();
// Client and connect a client
Client client = new Client();
client.connect();
// Sending one message to the server
client.sendMessage(new Message("MessageOne", 1));
// Sending another message to the server
client.sendMessage(new Message("MessageTwo", 2));
// Closing the client
client.disconnect();
}
}
问题可能是一个小细节,解决方案也可能就在我的眼前,但不知何故我看不到它。有没有人遇到过类似的问题?你是怎么解决的?
非常感谢和亲切的问候。
【问题讨论】:
标签: java multithreading sockets objectinputstream