gpt4 book ai didi

Java 如何使用 ObjectInputStream 进行读取

转载 作者:行者123 更新时间:2023-11-29 04:08:45 29 4
gpt4 key购买 nike

这是我第一次使用套接字,为了更好地了解发生了什么,我决定构建一个可以支持多个用户的客户端服务器聊天应用程序。

起初,我使用 DataInputStream/DataOutputStream 进行通信,一切正常。但我想切换到 ObjectStream,这就是问题所在。将所有 DataInputStream/DataOutputStream 替换为 ObjectInputStream/ObjectOutputStream 后,我将无法再打印检索到的数据。

这是我之前使用的代码,它可以工作(DataStream):

服务器:

       try {
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());

out.writeUTF("HI FROM SERVER");
while (!socket.isClosed()) {
try {
if (in.available() > 0) {
String input = in.readUTF();
for (ClientThread thatClient : server.getClients()){
DataOutputStream outputParticularClient = new DataOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeUTF(input + " GOT FROM SERVER");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}

客户:

try {
socket = new Socket("localhost", portNumber);


DataInputStream in = new DataInputStream(socket.getInputStream());
new Thread(()->{
while(!socket.isClosed()){
try {
if (in.available() > 0){
String input = in.readUTF();
System.out.println(getUserName() + " > " + input);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}

这就是我尝试用 ObjectStream 执行相同想法的方式:

服务器:

try {
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());

while (!socket.isClosed()) {
try {
if (in.available() > 0) {
Message input;
try {
input = (Message)in.readObject();
if (input.equals(null)){
System.err.println("SERVER RETRIEVED NULL OBJECT");
}
for (ClientThread thatClient : server.getClients()){
ObjectOutputStream outputParticularClient = new ObjectOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeObject(input);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}

客户:

try {
socket = new Socket(getHost(), portNumber);

ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
new Thread(()->{
while(!socket.isClosed()){
try {
if (in.available() > 0){
Message input = null;
try {
input = (Message)in.readObject();
if (input.equals(null)){
System.err.println("CLIENT RETRIEVED NULL OBJECT");
}
System.out.println("CLIENT " + input.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}

我觉得它与这个 if 语句 if (in.available() > 0) 有关,但我不能准确地说出发生了什么。

最佳答案

available()并不像您想象的那样工作,而且它在生产代码中几乎从来没有用处(对于 ObjectInputStream 尤其如此)。您没有收到任何数据的原因实际上是 in.available() 正如您已经怀疑的那样总是返回 0

如评论中所述,StreamCorruptedException 是由于写入现有的 ObjectInputStream 引起的,该 ObjectInputStream 已使用 ObjectOutputStream 的另一个实例写入>。比照。答案StreamCorruptedException: invalid type code: AC进一步解释。

这里是一些简单粗暴的示例代码,其中有一个服务器回显来自两个客户端的消息。它不干净,但它可能会让您了解如何解决您的问题:

public class SO56493162 {

private static final class Message implements Serializable {
private static final long serialVersionUID = 1L;
private static int cnt = 0;
private final int id;

public Message(int id) {
++cnt;
this.id = id;
}

public String toString() {
return "Msg from " + id + " : " + cnt;
}
}

private static final class Client implements Runnable {
private InetSocketAddress addr = null;
private int id = -1;

Client(InetSocketAddress addr, int id) {
this.addr = addr;
this.id = id;
}

public void run() {
int timeout = 3000;
Socket s = null;
try {
s = new Socket();
s.connect(addr, timeout);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
System.out.println("Client " + id + " connected");
while (true) {
Thread.sleep(new Random().nextInt(2000));
Message hello = new Message(id);
oos.writeObject(hello);
oos.flush();
Message reply = (Message) ois.readObject();
System.out.println("Reply: " + reply.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (Exception ignore) {
}
}
}
}

private static final class Server implements Runnable {
private ServerSocket sock = null;

Server(ServerSocket sock) throws IOException {
this.sock = sock;
}

public void run() {
System.out.println("starting server");
try {
while (true) {
final Socket client = sock.accept();
System.out.println("connection accepted");
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
while (!client.isClosed()) {
try {
Message input = (Message) ois.readObject();
oos.writeObject(input);
oos.flush();
} catch (EOFException eof) {
System.err.println("EOF!");
client.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.setDaemon(true);
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

public static void main(String args[]) throws IOException, InterruptedException {
final int port = 9876;

Thread ts = new Thread(new Runnable() {
@Override
public void run() {
try {
new Server(new ServerSocket(port)).run();
} catch (Exception e) {
e.printStackTrace();
}
}
});
ts.setDaemon(true);
ts.start();

InetSocketAddress addr = new InetSocketAddress("localhost", port);

for (int i = 0; i < 2; ++i) {
Client cl = new Client(addr, i);
Thread tc = new Thread(cl);
tc.setDaemon(true);
tc.start();
}

Thread.sleep(10000);
System.err.println("done");
}
}

关于Java 如何使用 ObjectInputStream 进行读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56493162/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com