这是我在Stack Overflow上的第一篇文章,所以我希望我能以最低限度的方式做到这一点。
我尝试使用Java套接字实现一个简单的解决方案,但我有一个例外。我肯定会滥用API,但我无法弄清楚原因和地点。
客户端需要向服务器发送多个二进制消息,并且它(客户端)必须重用相同的套接字。
在服务器中,我创建了一个执行两项操作的线程:(1)接受客户端请求;(2)实例化新线程(运行ClientWorker实例)以处理客户端请求。
如果我只是从客户端发送一条消息,一切正常。然而,当我尝试发送多条消息时,在第二条消息中我有以下异常:
java.io.StreamCorruptedException:无效的类型代码:AC at java.io.ObjectInputStream.readObject0(未知来源)at java.io.ObjectInputStream.readObject(未知来源)at simple.socketexample.ClientWorker.run(ClientWorker.java:26)at java.lang.Thread.run(未知来源)
异常发生在我的ClienWorker类中,在“Message message =(Message)in.readObject();”行中。请注意,服务器始终会成功接收第一条消息。
以下类是我为创建此错误而创建的简单示例的一部分。
第一堂课是讯息:
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;
}
}
}
}
我用过的课程测试了这个: package 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();
}
}
问题可能只是一个小细节,解决方案可能也在我的眼前,但不知怎的,我看不到它。有没有人遇到过类似的问题?你是怎么解决的?
非常感谢和亲切的问候。
答案 0 :(得分:2)
试试这个ClientWorker
public class ClientWorker implements Runnable {
private Socket socketFromClient;
public ClientWorker(Socket socketFromClient) {
super();
this.socketFromClient = socketFromClient;
}
public void run() {
while(true) {
ObjectInputStream in = null;
try {
in = new ObjectInputStream(socketFromClient.getInputStream());
} catch (IOException e) {
e.printStackTrace();
return;
}
try {
Message message = (Message)in.readObject();
System.out.println(message);
} catch (ClassNotFoundException e) {
e.printStackTrace();
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
并在客户端
中注释reset() public void sendMessage(Message message) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(serverSocket.getOutputStream());
out.writeObject(message);
out.flush();
// out.reset();
}