![](/img/trans.png)
[英]sending objects through TCP socket from java server to android client
[英]Java sending objects from queue or stack over TCP socket
我想使用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;
}
}
問題似乎出在您的while (to.value != 1)
。 服務器接收到第一個值為1的對象。它根本不執行while循環,而是立即關閉套接字。 因此,當客戶端嘗試從該套接字的輸入流創建ObjectInputStream
,它將遇到一個封閉的連接,在該連接處它會期望有一個對象流標頭。 因此EOFException
。
實現對話的最簡單方法是完全避免循環。 畢竟,您需要執行循環,然后在循環內進行區分大小寫,以在每次遍歷中執行特殊代碼。 您也可以編寫一個線性程序,並在需要時將通用代碼分解為方法調用,盡管您的示例幾乎沒有通用代碼。
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();
}
}
但是,由於在這種情況下,所有數據都是預先知道的,因此您可以不進行交錯處理,而是通過使用單獨的線程來接收數據,而在兩端立即發送所有數據,從而節省一些網絡往返時間。 但是,與您的示例相距甚遠,因此我將不包含代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.