Java 通过TCP/IP接收对象

Java 通过TCP/IP接收对象,java,sockets,tcp-ip,objectinputstream,Java,Sockets,Tcp Ip,Objectinputstream,我将在TCP/IP上编写一个程序,我应该通过客户端或服务器发送对象,当我想要发送或接收字符串时,这是正确的,但当我尝试读取对象时: private Socket client; public ThreadedClient(Socket client) { this.client = client; } @Override public void run() { try { ObjectInputStream objIn = new Object

我将在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)
这是我的服务器代码:

            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!");
            }

有人能告诉我发生了什么,这个异常是什么,以及我为什么收到这个异常吗?

如果你想通过网络发送对象,你必须序列化你的对象

检查此问题:

Java序列化:

你可以这样做:

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);}  
  }  
}  

不要发送和接收布尔值。这是多余的。如果创建连接时出现问题,则不会创建套接字:而是会引发异常。您将所有内容都与同一套接字上的多个流混淆。不要那样做


在read对象循环中,需要单独捕获EOFException,获得它后,关闭套接字并退出循环。如果您得到任何其他IOException,请记录它,关闭套接字,然后退出循环。

如果您希望获得良好的性能并发送对象,那么您肯定应该使用

它允许您在简单的.proto文件中定义消息。然后使用捆绑编译器生成Java类,这些类将被序列化并发送


另外,更好的方法是在普通Java套接字上使用。这会阻止您编写大量样板代码并定义简单的序列化/反序列化管道。查看。

显示变送器代码。我从项目中添加了一些代码,您还需要更多吗?这里没有证据表明发送的对象不可序列化。我想发送一个实现可序列化且具有SerialVersionId的客户端,在某些情况下,我想向服务器发送一个字符串,但是它不在ObjectInputStream objIn=newObjectInputStream(client.getInputStream())之后的行中;我认为这与可序列化无关,我理解您的代码,但我无法理解为什么会收到此异常。@AttilaBujáki您没有回答我的问题,但您的代码很有帮助,我感谢您的时间没有回答问题。OP并没有表示他对不断变化的技术持开放态度,因为他可能不知道任何替代方案。我的解决方案更容易实现,性能也更好。OP没有给出任何迹象表明他正在寻找替代方案。你的解决方案实际上并不能解决问题。这里没有证据表明你甚至知道问题是什么。我不知道你指的是什么“消息”,但如果你想知道问题是什么,请参阅我的答案。好的-现在我看到你更改了评论。我发现了我的问题,你是对的,我删除了不必要的代码,因此我理解问题。这是因为我试图通过printwriter发送字符串,但当我更改代码时,我试图通过objectInputStream接收该字符串,这导致了异常,我将printwriter更改为objectOutputStream,问题得到了解决,谢谢大家,但我不明白你们为什么说当我收到EOFEException时,我应该关闭循环,我有一个像推特这样的项目,我正处于起点。我应该在客户端运行时发送和接收对象,为什么要关闭套接字?1。不是。这是因为你在同一个套接字上使用了多个流,只有当它们都没有缓冲时,这才有效。。。但这仍然不是一个好主意。2.当您收到EOFEException时,表示对等方已关闭连接。没有更多的数据。永远不会有更多的数据。如果你不停地阅读,你只会得到EOFEException。不要。首先,我该怎么做?你是说通过arraylist和objectOutputStream发送我想要的不是一个好主意,然后我捕获arraylist的第一个成员,它是一个字符串,并通过它的值发送第二个成员,它可能是一个客户端或字符串,以便在服务器端执行某些操作?你有更好的主意吗?对于第二部分:我知道了,谢谢,这意味着客户注销了,所以我应该关闭套接字,对吗?1。我说了我说的。不要发送和接收布尔值。摆脱
扫描器
打印机。
通过一个流完成所有工作。2.我确实多次提到要关闭插座。
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);}  
  }  
}