gpt4 book ai didi

Java 通过 TCP 套接字从队列或堆栈发送对象

转载 作者:行者123 更新时间:2023-12-01 14:03:44 24 4
gpt4 key购买 nike

我想使用 TCP 在客户端/服务器之间发送/接收 12 个对象。对象是唯一的,但顺序始终相同。例如:客户端始终以发送“对象 1”开始,服务器始终以“对象 2”响应。如何设置队列或堆栈来执行此操作并仅使用 java 标准库同步对象的发送/接收?我已经编写了下面的代码(1 个包中的 3 个类文件),但它不起作用(文件结尾错误),但它显示了我的进展:

import java.net.*;
import java.io.*;

class SimpleClient {
public static void main(String args[]){
int counter = 0;
try{
Socket s = new Socket("localhost",2002);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
testobject to = new testobject(1,"object 1","field1","field2","field3","field4");
System.out.println("sending object 1"); //debug
oos.writeObject(to);
//Socket ss = s.accept();
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject too = (testobject)ois.readObject();
while (counter != 2) {
while ( too.value != 3 ) {
if (to==null) {
System.out.println("object is null!");
} else if (to.value==1){
System.out.println("receiving object 2"); //debug
System.out.println(to.id);
os = s.getOutputStream();
oos = new ObjectOutputStream(os);
testobject to0 = new testobject(2,"object 3","field1","field2","field3","field4");
oos.writeObject(to0);
System.out.println("object 3 sent!");
} else if (to.value==2){
System.out.println("receiving object 4"); //debug
System.out.println(to.id);
os = s.getOutputStream();
oos = new ObjectOutputStream(os);
testobject to0 = new testobject(3,"object 5","field1","field2","field3","field4");
oos.writeObject(to0);
System.out.println("sending object 5");
}
}
is.close();
s.close();
//System.out.println((String)ois.readObject());
counter = counter + 1;
}
oos.close();
os.close();
s.close();
} catch(Exception e) {
System.out.println(e);
}
}
}

class SimpleServer {
public static void main(String args[]) {
int port = 2002;
int counter = 0;
try {
ServerSocket ss = new ServerSocket(port);
while (counter != 1) {
Socket s = ss.accept();
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject to = (testobject)ois.readObject();
while ( to.value != 1 ) {
if (to==null) {
System.out.println("object is null!");
} else if (to.value==1){
System.out.println("receiving object 1"); //debug
System.out.println(to.id);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
testobject to0 = new testobject(2,"object 2","field1","field2","field3","field4");
oos.writeObject(to0);
System.out.println("sending object 2");
} else if (to.value==2){
System.out.println("receiving object 3"); //debug
System.out.println(to.id);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
testobject to0 = new testobject(4,"object 4","field1","field2","field3","field4");
oos.writeObject(to0);
System.out.println("sending object 4");
}
}
is.close();
s.close();
counter = counter + 1;
}
ss.close();
} catch(Exception e) {
System.out.println(e);
}
}
}

class testobject implements Serializable {
int value;
String id;
String field1;
String field2;
String field3;
String field4;
public testobject(int v, String s, String s1, String s2, String s3, String s4) {
this.value=v;
this.id=s;
this.field1 = s1;
this.field2 = s2;
this.field3 = s3;
this.field4 = s4;
}
}

最佳答案

代码中的 EOFException

问题似乎是你的while (to.value != 1)。服务器接收到第一个对象,其值为 1。它根本不执行 while 循环,而是立即关闭套接字。因此,当客户端尝试从该套接字的输入流创建 ObjectInputStream 时,它会遇到一个关闭的连接,它需要一个对象流 header 。因此,EOFException

实现对话

实现对话的最简单方法是完全避免循环。毕竟,您先执行循环,然后在循环中进行区分大小写,以在每次传递中执行特殊代码。您不妨编写一个线性程序,并根据需要将公共(public)代码分解到方法调用中,尽管您的示例几乎没有公共(public)代码。

class SimpleClient {
public static void main(String args[]) throws Exception {

// Connection setup
Socket s = new Socket("localhost",2002);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject to;

// Conversation

System.out.println("sending object 1");
to = new testobject(1,"object 1","field1","field2","field3","field4");
oos.writeObject(to);

System.out.println("receiving object 2");
to = (testobject)ois.readObject();
System.out.println(to.id);

System.out.println("sending object 3");
to = new testobject(2,"object 3","field1","field2","field3","field4");
oos.writeObject(to);

System.out.println("receiving object 4");
to = (testobject)ois.readObject();
System.out.println(to.id);

// Connection shutdown
ois.close();
oos.close();
s.close();
}
}

class SimpleServer {
public static void main(String args[]) throws Exception {

// Connection setup
ServerSocket ss = new ServerSocket(2002);
Socket s = ss.accept(); // only handle a single connection
ss.close(); // so we can immediately stop listening for more
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject to;

// Conversation

System.out.println("receiving object 1");
to = (testobject)ois.readObject();
System.out.println(to.id);

System.out.println("sending object 2");
to = new testobject(2,"object 2","field1","field2","field3","field4");
oos.writeObject(to);

System.out.println("receiving object 3");
to = (testobject)ois.readObject();
System.out.println(to.id);

System.out.println("sending object 4");
to = new testobject(4,"object 4","field1","field2","field3","field4");
oos.writeObject(to);

// Connection shutdown
ois.close();
oos.close();
s.close();
}
}

发送和接收队列

如果您确实想从队列中发送内容,您可以简单地迭代它。

import java.net.*;
import java.io.*;
import java.util.*;

class SimpleClient {
public static void main(String args[]) throws Exception {

// Preparing the queues
List<testobject> sendQueue = Arrays.asList(
new testobject(1,"object 1","field1","field2","field3","field4"),
new testobject(2,"object 3","field1","field2","field3","field4"));
List<testobject> receiveQueue = new ArrayList<testobject>();

// Connection setup
Socket s = new Socket("localhost",2002);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject to;

// Conversation, we start by sending
for (testobject toSend: sendQueue) {
System.out.println("Sending " + toSend.id);
oos.writeObject(toSend);
testobject received = (testobject)ois.readObject();
System.out.println("Received " + received.id);
receiveQueue.add(received);
}

// Connection shutdown
ois.close();
oos.close();
s.close();
}
}

class SimpleServer {
public static void main(String args[]) throws Exception {

// Preparing the queues
List<testobject> sendQueue = Arrays.asList(
new testobject(2,"object 2","field1","field2","field3","field4"),
new testobject(4,"object 4","field1","field2","field3","field4"));
List<testobject> receiveQueue = new ArrayList<testobject>();

// Connection setup
ServerSocket ss = new ServerSocket(2002);
Socket s = ss.accept(); // only handle a single connection
ss.close(); // so we can immediately stop listening for more
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject to;

// Conversation, we start by receiving
for (testobject toSend: sendQueue) {
testobject received = (testobject)ois.readObject();
System.out.println("Received " + received.id);
receiveQueue.add(received);
System.out.println("Sending " + toSend.id);
oos.writeObject(toSend);
}

// Connection shutdown
ois.close();
oos.close();
s.close();
}
}

但由于在这种情况下,所有数据都是预先知道的,因此您可以通过不交错事物来节省一些网络往返,而是立即在两端发送所有数据,使用单独的线程来接收事物。但是,这与您的示例相差甚远,因此我不会包含相关代码。

关于Java 通过 TCP 套接字从队列或堆栈发送对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19108519/

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