Java通过TCP套接字从队列或堆栈发送对象
我想使用TCP在客户机/服务器之间发送/接收12个对象。对象是唯一的,但序列始终相同。例如:客户端总是以发送“对象1”开始,服务器总是以“对象2”响应。我如何设置队列或堆栈来实现这一点,并仅使用java标准库同步对象的发送/接收?我已经编写了下面的代码(1个包中的3个类文件),但它不起作用(文件结束错误),但它显示了我所处的位置:Java通过TCP套接字从队列或堆栈发送对象,java,sockets,tcp,Java,Sockets,Tcp,我想使用TCP在客户机/服务器之间发送/接收12个对象。对象是唯一的,但序列始终相同。例如:客户端总是以发送“对象1”开始,服务器总是以“对象2”响应。我如何设置队列或堆栈来实现这一点,并仅使用java标准库同步对象的发送/接收?我已经编写了下面的代码(1个包中的3个类文件),但它不起作用(文件结束错误),但它显示了我所处的位置: import java.net.*; import java.io.*; class SimpleClient { public static void m
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;
}
}
代码中的EOFEException
问题似乎是您的while(to.value!=1)
。服务器接收第一个对象,值为1。它根本不执行while循环,而是立即关闭套接字。因此,当客户机尝试从该套接字的输入流创建ObjectInputStream
时,它会遇到一个闭合连接,在该连接中,它会期望一个对象流头。因此,EOFEException
实施对话
实现对话的最简单方法是完全避免循环。毕竟,您执行了循环,但随后在循环中进行了区分大小写,以便在每个过程中执行特殊代码。您还可以编写一个线性程序,并在需要时将公共代码考虑到方法调用中,尽管您的示例几乎没有公共代码
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();
}
}
import java.net.*;
导入java.io.*;
导入java.util.*;
类SimpleClient{
公共静态void main(字符串args[])引发异常{
//准备队列
List sendQueue=Arrays.asList(
新的测试对象(1,“对象1”、“字段1”、“字段2”、“字段3”、“字段4”),
新的测试对象(2,“对象3”、“字段1”、“字段2”、“字段3”、“字段4”);
List receiveQueue=new ArrayList();
//连接设置
套接字s=新套接字(“本地主机”,2002年);
OutputStream os=s.getOutputStream();
ObjectOutputStream oos=新的ObjectOutputStream(os);
InputStream=s.getInputStream();
ObjectInputStream ois=新ObjectInputStream(is);
测试对象到;
//对话,我们从发送
用于(testobject toSend:sendQueue){
System.out.println(“发送”+toSend.id);
oos.writeObject(toSend);
testobject received=(testobject)ois.readObject();
System.out.println(“已接收”+已接收.id);
receiveQueue.add(已接收);
}
//连接关闭
ois.close();
oos.close();
s、 close();
}
}
类SimpleServer{
公共静态void main(字符串args[])引发异常{
//准备队列
List sendQueue=Arrays.asList(
新的测试对象(2,“对象2”、“字段1”、“字段2”、“字段3”、“字段4”),
新的测试对象(4,“对象4”、“字段1”、“字段2”、“字段3”、“字段4”);
List receiveQueue=new ArrayList();
//连接设置
ServerSocket ss=新的ServerSocket(2002年);
套接字s=ss.accept();//仅处理单个连接
ss.close();//这样我们就可以立即停止收听更多内容
OutputStream os=s.getOutputStream();
ObjectOutputStream oos=新的ObjectOutputStream(os);
InputStream=s.getInputStream();
ObjectInputStream ois=新ObjectInputStream(is);
测试对象到;
//对话,我们从接收开始
用于(testobject toSend:sendQueue){
testobject received=(testobject)ois.readObject();
System.out.println(“已接收”+已接收.id);
receiveQueue.add(已接收);
System.out.println(“发送”+toSend.id);
oos.writeObject(toSend);
}
//连接关闭
ois.close();
oos.close();
s、 close();
}
}
但是,由于在这种情况下,所有数据都是预先知道的,因此您可以通过不交错内容而在两端立即发送所有数据,使用单独的线程接收内容来节省一些网络往返。但是,这与您的示例相差甚远,因此我将不包括这方面的代码。您应该改进格式。没人会读的!抱歉,愚蠢地未检查剪切/粘贴错误。请不要在同一套接字上继续创建新的
ObjectInputStreams
和ObjectOutputStreams
。在插座的使用寿命内使用相同的插座;然后首先创建ObjectOutputStream
。这就是EOF错误的答案。非常感谢。按照从堆栈或队列到堆栈或队列的顺序发送/接收对象的方法如何?@Matt1993:我想我不完全理解您在这方面的问题。通过堆栈和队列,我将一系列对象关联起来,这样您就可以简单地对它们进行迭代。另一方面,您的示例似乎表示某种形式的对话,其中发送的消息取决于在此之前收到的消息。我将在我的帖子中包括这两个问题的答案。谢谢MvG这两个答案都会很有帮助,但作为参考,我尝试做的是模拟TCP握手协议。客户机使用客户机\你好进行初始化,服务器使用服务器\你好进行响应,每个对象(例如服务器\你好)包含字段(2-3个字符串)。