大家好,在此先感谢那些阅读以下内容的人:
我正在尝试发送对象“配置文件”的ArrayList(我使它可序列化),但要一个接一个地发送(因为列表的末尾将被其他线程填充,但这不是问题)。
我在“clientconnexion”(即客户端)和“clientprocessor”(即服务器)之间使用套接字。它们位于不同的线程中,最后它们将位于不同的计算机上。
当我尝试使用以下代码(尝试发送50个配置文件)时,我确实收到了其中一些(例如前20个,或前30个,有时甚至全部或全部都没有...),但clientconnexion停止接收一次查看个人资料...
这是代码:
类Profile
:
public class Profile implements Serializable {
private static final long serialVersionUID = 2406276545874892098L;
public int id;
public String name;
public Profile(String name, int id){
this.id=id;
this.name=name;
}
}
类
Server
(接受连接并启动clientprocessor线程,它仅启动一个线程,因此它现在并不是真正有用,但它将在之后):public class serveur {
private int port;
private String host = "0.0.0.0";
private ServerSocket server = null;
private boolean isRunning = true;
public serveur(String pHost, int pPort){
host = pHost;
port = pPort;
try {
server = new ServerSocket(port, 100, InetAddress.getByName(host));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void open(){
Thread t = new Thread(new Runnable(){
public void run(){
while(isRunning == true){
try {
Socket client = server.accept();
client.setTcpNoDelay(true);
Thread t = new Thread(new clientprocessor(client));
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
server = null;
}
}
});
t.start();
}
public void close(){
isRunning = false;
}
}
类
clientprocessor
:public class clientprocessor implements Runnable {
private Socket client;
private BufferedOutputStream bos=null;
private BufferedInputStream bis=null;
private BufferedWriter writer=null;
private BufferedReader reader=null;
private ArrayList<Profile> profilesToSend;
public clientprocessor (Socket client){
this.client = client;
this.profilesToSend=new ArrayList<>();
for (int i=1; i<51; i++){
this.profilesToSend.add(new Profile("test", i));
}
}
public synchronized Profile getProfile () {
Iterator<Profile> itr = this.profilesToSend.iterator();
if (itr.hasNext()){
Profile P = itr.next();
itr.remove();
return P;
}
return null;
}
public void run (){
try {
bos= new BufferedOutputStream (client.getOutputStream());
bis= new BufferedInputStream (client.getInputStream());
writer=new BufferedWriter(new OutputStreamWriter(bos));
reader=new BufferedReader(new InputStreamReader(bis));
ObjectOutputStream oos=new ObjectOutputStream(bos);
Profile P;
while ((P = this.getProfile())!=null) {
writer.write(0); //when the client receive a zero, e knows he will receive a profile
writer.flush();
oos.writeObject(P);
oos.flush();
System.out.println("clientprocessor : profile written (" + P.name + " " +P.id +")");
int i=reader.read(); //Waiting to receive a one to be sure that the object was received
System.out.println("clientprocessor : integer received : " +i);
}
System.out.println("--------clientprocessor : all profiles sent--------");
writer.write(1); //when the client receive a one he knows he will not receive profiles anymore
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.close();
reader.close();
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
类
clientconnexion
(应该在末尾的另一台计算机上):public class clientconnexion implements Runnable {
private Socket connexion;
private BufferedOutputStream bos=null;
private BufferedInputStream bis=null;
private BufferedWriter writer=null;
private BufferedReader reader=null;
public clientconnexion(String adress, int port) {
try {
connexion = new Socket(adress, port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
connexion.setTcpNoDelay(true);
bos= new BufferedOutputStream (connexion.getOutputStream());
bis= new BufferedInputStream (connexion.getInputStream());
writer=new BufferedWriter(new OutputStreamWriter(bos));
reader=new BufferedReader(new InputStreamReader(bis));
ObjectInputStream ois = new ObjectInputStream(bis);
int k = reader.read();
String S="clientconnexion : profiles received : ";
while (k==0){
System.out.println("clientconnexion : waiting for an object to read");
Profile P=(Profile)ois.readObject();
S = S + P.name + " " + P.id+ " ; ";
System.out.println(S);
writer.write(1);//the client sends a 1 to the server (clientprocessor)
writer.flush();
k=reader.read();
}
} catch (IOException e) {
System.out.println(e);
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
bis.close();bos.close();reader.close();writer.close();
System.out.println("clientconnexion : streams closed");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最后是
test
类,它将启动所有这些:public class test {
public static String adresse = "localhost";
public static int port = 9028;
public static void main(String[] args) {
serveur serveur = new serveur ("0.0.0.0",port);
System.out.println("--Test : serveur créé");
serveur.open();
System.out.println("Test : serveur ouvert");
Thread tclient1= new Thread(new clientconnexion(adresse, port));tclient1.start();
}
如您所见,我尝试使用
setTCPnoDelay
,但显然这不是问题的原因。非常感谢您阅读并能运行此代码并告诉我是否存在相同的问题...
最佳答案
问题在于clientprocessor
类中,ObjectOutputStream
和BufferedWriter
无法连接到同一流。同样,在clientconnexion
类中,ObjectInputStream
和BufferedReader
都无法连接到同一流。以下更改应该起作用clientprocessor
类
try {
bos= new BufferedOutputStream (client.getOutputStream());
bis= new BufferedInputStream (client.getInputStream());
//writer=new BufferedWriter(new OutputStreamWriter(bos));
reader=new BufferedReader(new InputStreamReader(bis));
ObjectOutputStream oos=new ObjectOutputStream(bos);
Profile P;
while ((P = this.getProfile())!=null) {
//writer.write(0); //when the client receive a zero, e knows he will receive a profile
//writer.flush();
oos.write(0);
oos.flush();
oos.writeObject(P);
oos.flush();
System.out.println("clientprocessor : profile written (" + P.name + " " +P.id +")");
int i=reader.read(); //Waiting to receive a one to be sure that the object was received
System.out.println("clientprocessor : integer received : " +i);
}
System.out.println("--------clientprocessor : all profiles sent--------");
//writer.write(1); //when the client receive a one he knows he will not receive profiles anymore
//writer.flush();
oos.write(1);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//writer.close();
reader.close();
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
clientconnexion
类try {
connexion.setTcpNoDelay(true);
bos= new BufferedOutputStream (connexion.getOutputStream());
bis= new BufferedInputStream (connexion.getInputStream());
writer=new BufferedWriter(new OutputStreamWriter(bos));
//reader=new BufferedReader(new InputStreamReader(bis));
ObjectInputStream ois = new ObjectInputStream(bis);
int k = ois.read();
String S="clientconnexion : profiles received : ";
while (k==0){
System.out.println("clientconnexion : waiting for an object to read");
Profile P=(Profile)ois.readObject();
S = S + P.name + " " + P.id+ " ; ";
System.out.println(S);
writer.write(1);//the client sends a 1 to the server (clientprocessor)
writer.flush();
k=ois.read();
}
} catch (IOException e) {
System.out.println(e);
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
bis.close();
bos.close();
//reader.close();
writer.close();
System.out.println("clientconnexion : streams closed");
} catch (IOException e) {
e.printStackTrace();
}
}