I want to send/receive 12 objects between client/server using TCP. The objects are unique but the sequence is always the same. For example: client always starts by sending "object 1" and server always responds with "object 2." How do I set up a queue or stack to do this and synchronise the sending/receiving of objects using only the java standard library? I have worked on the code below (3 class files from 1 package) and it does not work (end of file error) but it shows where I am up to:
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;
}
}
The problem seems to be your while (to.value != 1)
. The server receives the first object, with value 1. It does not execute that while loop at all, but instead closes the socket immediately. So when the client tries to create an ObjectInputStream
from the input stream of that socket, it encounters a closed connection where it would expect an object stream header. Thus the EOFException
.
The easiest way to implement a conversation is avoiding the loops altogether. After all, you do the loop but then do a case distinction within the loop to execute special code in each pass. You might as well write a linear program, and factor common code into method calls if needed, although your example has little common code.
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();
}
}
If you really want to send stuff from a queue, you can simply iterate over it.
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();
}
}
But since in this case, all the data is known up front, you might save some network round trips by not interleaving things, but instead sending all data at both ends immediately, using a separate thread to receive things. However, that would be even further away from your example, so I'll not include code for this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.