Отправка вектора объектов по сети - PullRequest
0 голосов
/ 28 сентября 2010

Хорошо, поэтому я пишу тестовую программу для отправки вектора объектов с сервера на клиент.

-Server-

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

public class TestServer{
    public static void main(String[] args) throws IOException {

        Vector<Obj> obj = new Vector<Obj>();
        obj.add(new Obj(5));
        obj.add(new Obj(4));
        obj.add(new Obj(7));
        obj.add(new Obj(8));
        obj.add(new Obj(2));

        ServerSocket serverSocket = new ServerSocket(4444);
        boolean listening = true;

        while(listening){
            new ClientThread(serverSocket.accept(), obj).start();
        }

        serverSocket.close();
        System.exit(0);
    }
}

class ClientThread extends Thread implements Runnable{
    Socket acceptedSocket;
    Vector<Obj> obj;

    public ClientThread(Socket acceptedSocket, Vector<Obj> obj){
        super("ClientThread");
        this.acceptedSocket = acceptedSocket;
        this.obj = obj;
    }

    public void run(){
        try{
            Socket clientSocket = acceptedSocket;
            clientSocket.setTcpNoDelay(true);
            System.out.println("Accepted. Now creating I/O.\n");
            DataInputStream in = new DataInputStream(clientSocket.getInputStream());
            ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
            System.out.println("player connected. \n");
            out.writeObject(obj);
            out.flush();

            while(true){
                out.writeObject(obj);
                out.flush();

               sleep(15);
            }

        }

        catch(Exception e){
            e.printStackTrace();
            System.exit(1);
        }


    }
}

class Obj implements Serializable{
    int i;

    public Obj(int i){
        this.i = i;
    }
}

-Client-

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

import javax.swing.JOptionPane;


public class TestClient {

    static Vector<Obj> obj;
    static ClientThread ct;

    public static void main(String[] args){
        obj = new Vector<Obj>();
        connect();

        for(int i = 0; i < obj.size(); i++){
            System.out.println("Obj: " + obj.get(i).i);
        }

        System.exit(0);
    }

    public static void connect(){
        String ip = JOptionPane.showInputDialog("Input server IP.");
        ct = new ClientThread(ip, obj);
        ct.start();
        ct.setPriority(Thread.MAX_PRIORITY);
    }
}

class Obj implements Serializable{
    int i;

    public Obj(int i){
        this.i = i;
    }
}

class ClientThread extends Thread implements Runnable{
    Socket socket;
    Vector<Obj> obj;
    DataOutputStream out;
    ObjectInputStream in;
    boolean loop = true;

    @SuppressWarnings("unchecked")
    public ClientThread(String ip, Vector<Obj> obj){
        super("ClientThread");

        try{
            socket = new Socket(ip, 4444);
            socket.setTcpNoDelay(true);
            out = new DataOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());
            this.obj = obj; 
            this.obj = (Vector<Obj>) in.readObject();
        }

        catch(Exception e){
            e.printStackTrace();
        }
    }

    public void run(){
        try{
            while(loop){
                try{
                    if(!socket.isClosed() && socket.isConnected()){         
                        obj = (Vector<Obj>) in.readObject();
                        this.sleep(15);
                    }

                    else
                        loop = false;

                }
                catch(Exception e){
                        e.printStackTrace();
                        socket.close();
                }  
            }



        }

        catch(Exception e){
            e.printStackTrace();
        }
    }
}

Порт 4444 был открыт.

Получение этой ошибки:

Accepted. Now creating I/O.

player connected. 

java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(Unknown Source)
    at java.net.SocketOutputStream.write(Unknown Source)
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
    at java.io.ObjectOutputStream.writeNonProxyDesc(Unknown Source)
    at java.io.ObjectOutputStream.writeClassDesc(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeFatalException(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at ClientThread.run(TestServer.java:49)

Ответы [ 2 ]

1 голос
/ 28 сентября 2010

Вы получили эту ошибку, потому что клиент завершил работу с System.exit (0) в строке 21, которая закрыла соединение, , и вы продолжали запись в соединение на одном конце после того, как оно было закрыто на другом конце. Это либо нереалистичная ситуация, в этом случае вам не следует этого делать, либо это реалистичная ситуация, и в этом случае вы должны ожидать, что получит сброс соединения при записи.

1 голос
/ 28 сентября 2010

Вы получили эту ошибку, потому что клиент завершает с System.exit (0); звоните по линии 21.

Я вижу, что это всего лишь тест, но также неплохо писать осторожный код в тестах. использовать правильные модификаторы видимости - закрыть потоки в блоке наконец - используйте ArrayList вместо Vector, если вам не нужна безопасность потоков при работе с ним -etc

Этот код содержит много потенциальных ошибок, поэтому реальная (довольно простая) проблема не была замечена на первом сайте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...