我将通过TCP / IP编写一个程序,我应该通过客户端或服务器发送对象,当我想发送或接收字符串但是当我试图读取一个对象时,它是正确的:
private Socket client;
public ThreadedClient(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
ObjectInputStream objIn = new ObjectInputStream(client.getInputStream());
while(true){
try {
Object fromClient = objIn.readObject();
} catch (ClassNotFoundException e) {e.printStackTrace();}
}
} catch (IOException e) {e.printStackTrace();}
}
我收到一个例外:
java.io.StreamCorruptedException: invalid stream header: 306E6165
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.bihe.serverSocket.ThreadedClient.run(Server.java:137)
at java.lang.Thread.run(Unknown Source)
它指的是这一行:
ObjectInputStream objIn = new ObjectInputStream(client.getInputStream());
这是我的服务器代码:
ServerSocket ss = new ServerSocket(8800);
while(true){
Socket newClient = ss.accept();
System.out.println(">>>> Client number " + (++counter) + " connected.");
OutputStream outputStream = newClient.getOutputStream();
PrintWriter sender = new PrintWriter(outputStream);
sender.println(true);
sender.flush();
ThreadedClient client = new ThreadedClient(newClient);
clients.add(client);
new Thread(client).start();
客户端代码:
sc = new Socket("127.0.0.1", 8800);
InputStream inputStream = sc.getInputStream();
Scanner scanner = new Scanner(inputStream);
boolean s = scanner.nextBoolean();
if(s){
System.out.println("Client connected successfully.");
return true;
}else{
System.out.println("Ohhh, Some problem happened, try again later!");
}
任何人都可以解释我发生了什么,这个例外是什么以及为什么我收到这个例外?
答案 0 :(得分:5)
如果您想通过网络发送对象,则必须序列化您的对象。
检查此问题: How To send an object over TCP in Java
Java序列化: Serialization
你可以这样做:
import java.net.*;
import java.io.*;
class testobject implements Serializable {
int value;
String id;
public testobject(int v, String s ){
this.value=v;
this.id=s;
}
}
public class SimpleServer {
public static void main(String args[]) {
int port = 2002;
try {
ServerSocket ss = new ServerSocket(port);
Socket s = ss.accept();
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject to = (testobject)ois.readObject();
if (to!=null){System.out.println(to.id);}
System.out.println((String)ois.readObject());
is.close();
s.close();
ss.close();
}catch(Exception e){System.out.println(e);}
}
}
import java.net.*;
import java.io.*;
public class SimpleClient {
public static void main(String args[]){
try{
Socket s = new Socket("localhost",2002);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
testobject to = new testobject(1,"object from client");
oos.writeObject(to);
oos.writeObject(new String("another object from the client"));
oos.close();
os.close();
s.close();
}catch(Exception e){System.out.println(e);}
}
}
答案 1 :(得分:3)
摆脱发送和接收布尔值。这是多余的。如果创建连接时出现问题,则不会创建套接字:将抛出异常。您在同一个套接字上混淆了多个流的所有内容。不要那样做。
在read-object循环中,你需要单独捕获EOFException,当你得到它时,关闭套接字并退出循环。如果您收到任何其他IOException,请记录它,关闭套接字,然后退出循环。
答案 2 :(得分:1)
如果您希望获得良好的性能并发送对象,那么您绝对应该使用Google Protobuf
它允许您在简单的.proto文件中定义消息。然后使用捆绑的编译器生成将被序列化并发送的Java类。
更好的想法是使用Netty而不是普通的Java套接字。这可以防止您编写大量样板代码并定义简单的序列化/反序列化管道。看看user-guide。