Android:从服务器上的套接字接收空对象

时间:2014-02-23 21:58:09

标签: java android sockets

我有一个服务器/客户端应用程序,用于发送/接收有关应用程序用户(成员)的更新。不幸的是,当Android设备上的客户端发送任何getUpdate / sendUpdate对象时,服务器会将它们作为空接收。

我还有一个PC版的Android客户端,完全正常。它有相同的方法和一切。

以下是Android设备上的客户端:

public class AndroidApplication extends Application{
public static Log log;

private final static String TAG = "AndroidApplication";
public static final String SERVER = "192.168.1.136";

public static boolean chatCreated = false;
public static String chatText;
public static String username, level = MemberMessage.LEVEL4;
public static Context context;
public static int points = 0;

public static UpdateMember k;
@Override
public void onCreate(){
    super.onCreate();
    context = getApplicationContext();
}

public static void updateMember(){
    k = new UpdateMember(UpdateMember.SEND);
    k.start();
}
public static void getUpdateMember(){
    k = new UpdateMember(UpdateMember.GET);
    k.start();
}
public static void stopUpdateMember(){
    AndroidApplication.k = null;
}
static class UpdateMember extends Thread{
    static final int GET=0,SEND=1;

    boolean didConnectWork;
    boolean didUpdateWork;
    boolean didDisconnectWork;
    Socket socket;
    ObjectInputStream sInput;
    ObjectOutputStream sOutput;
    boolean GetSend;

    public UpdateMember(int get_send){
        switch(get_send){
        case UpdateMember.GET:
            GetSend = true;
            break;
        case UpdateMember.SEND:
            GetSend = false;
            break;
        }

    }

    public void run(){
        if(GetSend){
            didConnectWork = connect();
            didUpdateWork = getUpdate();
            getInfoFromServer();
            didDisconnectWork = disconnect();
        }else{
            didConnectWork = connect();
            didUpdateWork = sendUpdate();
            try{
            getInfoFromServer();
            }catch(Exception e){
                Log.i(TAG, "Something Bad");
            }
            didDisconnectWork = disconnect();
        }
        AndroidApplication.stopUpdateMember();
    }

    private boolean connect() {
        try{
            socket = new Socket(SERVER, 1520);
        }catch(Exception e){
            Log.i(TAG, "Couldn't connect to Member Server");
            Log.i(TAG, e.getMessage());
            return false;
        }
        Log.i(TAG, "Connection Accepted at Membe Server!");

        /*
         * Create both data streams
         */
        try{
            sInput = new ObjectInputStream(socket.getInputStream());
            sOutput = new ObjectOutputStream(socket.getOutputStream());
        }catch(IOException e){
            Log.i(TAG, "Couldn't connect to Member Server");
            return false;
        }
        try{
            sOutput.writeObject(username);
        }catch(IOException e){
            Log.i(TAG, "Couldn't send username.");
            return false;
        }
        //everything worked
        Log.i(TAG, "Connected to Member Server.");

        return true;
    }

    private boolean sendUpdate() {
        MemberMessage mh = new MemberMessage(MemberMessage.UPDATE, AndroidApplication.username,
                AndroidApplication.points, AndroidApplication.level);
        try{
            sOutput.writeObject(mh);
        }catch(IOException e){
            Log.i(TAG, "Couldn't update info");
            return false;
        }
        //everything worked!
        Log.i(TAG, Integer.toString(mh.getType()));
        Log.i(TAG, "Update sent!");

        return true;
    }
    private boolean getUpdate(){
        try{
            sOutput.writeObject(new MemberMessage(MemberMessage.UPDATE_REQUEST,
                    AndroidApplication.username, -1, null));
        }catch(IOException e){
            Log.i(TAG, "Couldn't send GET message info");
            return false;
        }
        //itworked
        Log.i(TAG, "GET Update sent!");

        return true;
    }
    private void getInfoFromServer(){
        MemberMessage MM;
        /*
         * Will listen for both an update message and a Diconnect messafge form the
         * server.
         */
        boolean keep = true;
        while(keep){
            //************************************
            try{
                MM = (MemberMessage) sInput.readObject();
            }catch(IOException e){
                Log.i(TAG, "Couldn't read message from server.");
                break;
            } catch (ClassNotFoundException e) {
                Log.i(TAG, "Couldn't update info");
                break;
            }
            //the message to stop listening for updates
            switch(MM.getType()){
            case MemberMessage.DISCONECT:
                Log.i(TAG, "Received dsconnect message.");
                keep = false;
                break;
            case MemberMessage.UPDATE:
                /*
                 * Update our info in turn
                 */
                AndroidApplication.points = MM.getNumPoints();
                AndroidApplication.level = MM.getLevel();
                Log.i(TAG, "Updatted member with Points = " + AndroidApplication.points
                        + " and Level = " + AndroidApplication.level);
                try{
                    //tell the sever we recieved the info
                    sOutput.writeObject(new MemberMessage(MemberMessage.RECIEVED, null, -1, null));
                }catch(IOException e){
                    Log.i(TAG, "Couldn't send received message");
                    keep = false;
                }
                break;
            }
            //*****************************************     
        }

    }

    private boolean disconnect() {
        try{
            sOutput.writeObject(new MemberMessage(MemberMessage.DISCONECT, null, -1, null));
        }catch(IOException e){
            Log.i(TAG, "Couldn't disconnet");
        }
        // try to close the connection
        try {
            if(sOutput != null) sOutput.close();
        }
        catch(Exception e) {
            Log.i(TAG, "Couldn't close output");
            return false;
        }
        try {
            if(sInput != null) sInput.close();
            }
        catch(Exception e) {
            Log.i(TAG, "Couldn't close input");
            return false;
        }
        try {
            if(socket != null) socket.close();
        }
        catch (Exception e) {
            Log.i(TAG, "Couldn't close socket");
            return false;
        }
        return true;    
    }
}
}

对于PC版:

public class UpdateTest {
public static final String SERVER = "192.168.1.136";

public static boolean chatCreated = false;
public static String chatText;
public static String username = "TESTER", level = MemberMessage.LEVEL1;
public static int points = 90;

public static UpdateMember k;

public static void updateMember(){
    k = new UpdateMember(UpdateMember.SEND);
    k.start();
}
public static void getUpdateMember(){
    k = new UpdateMember(UpdateMember.GET);
    k.start();
}
public static void stopUpdateMember(){
    UpdateTest.k = null;
}
static class UpdateMember extends Thread{
    static final int GET=0,SEND=1;

    boolean didConnectWork;
    boolean didUpdateWork;
    boolean didDisconnectWork;
    Socket socket;
    ObjectInputStream sInput;
    ObjectOutputStream sOutput;
    boolean GetSend;

    public UpdateMember(int get_send){
        switch(get_send){
        case UpdateMember.GET:
            GetSend = true;
            break;
        case UpdateMember.SEND:
            GetSend = false;
            break;
        }

    }

    public void run(){
        if(GetSend){
            didConnectWork = connect();
            didUpdateWork = getUpdate();
            getInfoFromServer();
            didDisconnectWork = disconnect();
        }else{
            didConnectWork = connect();
            didUpdateWork = sendUpdate();
            getInfoFromServer();
            didDisconnectWork = disconnect();
        }
        UpdateTest.stopUpdateMember();
    }

    private boolean connect() {
        try{
            socket = new Socket(SERVER, 1520);
        }catch(Exception e){

            return false;
        }


        /*
         * Create both data streams
         */
        try{
            sInput = new ObjectInputStream(socket.getInputStream());
            sOutput = new ObjectOutputStream(socket.getOutputStream());
        }catch(IOException e){

            return false;
        }
        try{
            sOutput.writeObject(username);
        }catch(IOException e){

            return false;
        }
        //everything worked

        return true;
    }

    private boolean sendUpdate() {
        try{
            sOutput.writeObject(new MemberMessage(MemberMessage.UPDATE, UpdateTest.username,
                    UpdateTest.points, UpdateTest.level));
        }catch(IOException e){

            return false;
        }
        //everything worked!


        return true;
    }
    private boolean getUpdate(){
        try{
            sOutput.writeObject(new MemberMessage(MemberMessage.UPDATE_REQUEST,
                    UpdateTest.username, -1, null));
        }catch(IOException e){

            return false;
        }
        //itworked

        return true;
    }
    private void getInfoFromServer(){
        MemberMessage MM;
        /*
         * Will listen for both an update message and a Diconnect messafge form the
         * server.
         */
        boolean keep = true;
        while(keep){
            //************************************
            try{
                MM = (MemberMessage) sInput.readObject();
            }catch(IOException e){

                break;
            } catch (ClassNotFoundException e) {

                break;
            }
            //the message to stop listening for updates
            switch(MM.getType()){
            case MemberMessage.DISCONECT:
                keep = false;
                break;
            case MemberMessage.UPDATE:
                /*
                 * Update our info in turn
                 */
                UpdateTest.points = MM.getNumPoints();
                UpdateTest.level = MM.getLevel();

                try{
                    //tell the sever we received the info
                    sOutput.writeObject(new MemberMessage(MemberMessage.RECIEVED, null, -1, null));
                }catch(IOException e){

                    keep = false;
                }
                break;
            }
            //*****************************************     
        }

    }

    private boolean disconnect() {
        System.out.println("Disconectin...");
        System.out.println(UpdateTest.username);

        System.out.println(UpdateTest.points);

        System.out.println(UpdateTest.level);

        try{
            sOutput.writeObject(new MemberMessage(MemberMessage.DISCONECT, null, -1, null));
        }catch(IOException e){

        }
        // try to close the connection
        try {
            if(sOutput != null) sOutput.close();
        }
        catch(Exception e) {

            return false;
        }
        try {
            if(sInput != null) sInput.close();
            }
        catch(Exception e) {

            return false;
        }
        try {
            if(socket != null) socket.close();
        }
        catch (Exception e) {

            return false;
        }
        return true;    
    }
}
public static void main(String... args){
    updateMember();
    getUpdateMember();
}
}

现在服务器:

public class MemberServer {
// a unique ID for each connection
private static int uniqueId;
//ArrayList of connected members
private static ArrayList<Member> ml;
//Arraylist of the Created user profiles
private static ArrayList<String> members = new ArrayList<String>();
//the port to be run on
static private final int PORT = 1520;
//will keep the server running
static private boolean keepGoing;

public MemberServer(){
    ml = new ArrayList<Member>();
    readUserList();
}
private void readUserList() {
    BufferedReader in = null;
    try{
        in = new BufferedReader(new FileReader("/home/steven/Documents/Android/MemberServerTest/Users.txt"));
        String str = in.readLine();
        while((str = in.readLine()) != null){
            members.addAll(Arrays.asList(str.split(",")));
        }
    }catch(IOException e){
        e.printStackTrace();
    }
}
public void begin(){
    keepGoing = true;
    /*
     * Create a socket server and wait for connections
     */
    try{
        ServerSocket serverSocket = new ServerSocket(1520);

        //loop to wait for connections
        while(keepGoing){
            //message to say that we are waiting
            display("Server is waiting for Members on port " + PORT + ".");

            Socket socket = serverSocket.accept();// acctep connection
            //if asked to stop
            if(!keepGoing){
                break;
            }
            Member m = new Member(socket);
            ml.add(m);
            m.start();
        }
        try{
            serverSocket.close();
            for(int i = 0; i < ml.size(); ++i){
                Member mb = ml.get(i);
                try{
                    mb.sInput.close();
                    mb.sOutput.close();
                    mb.socket.close();
                    mb.createUserData(mb.username);
                }catch(IOException ioE){}
            }
        }catch(Exception e){}
        Writer o = null;
        o = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream("/home/steven/Documents/Android/MemberServerTest/Users.txt" ), "utf-8"));
        o.write("\n");
        for(Member k:ml){
            o.write(k.username + ",");
        }
        o.close();
    }catch(IOException e){
        e.printStackTrace();
    }
}
protected static void stop(){
    System.out.println("Now Stoping Server...");
    keepGoing = false;
    try{
        new Socket("localhost", PORT);
    }catch(Exception e){}
}
private void display(String string) {
    System.out.println(string);
}
synchronized static void remove(int id){
    for(Member mn: ml){
        if(mn.id == id){
            ml.remove(mn);
            return;
        }
    }
}
public static void main(String... args){
    MemberServer ms = new MemberServer();
    ms.begin();
}

class Member extends Thread{
    Socket socket;
    ObjectInputStream sInput;
    ObjectOutputStream sOutput;

    public ArrayList<String> properties = new ArrayList<String>();
    public  int id;
    public  String username,level = MemberMessage.LEVEL4;
    public  int numPoints = 0, numUpvotes = 0;
    public  MemberMessage memMes;

    Member(Socket socket){
        boolean exists = false;
        id = ++uniqueId;
        this.socket = socket;
        System.out.println("Thread trying to create Object Input/Output Streams");
        try{
            //create output first
            sOutput = new ObjectOutputStream(socket.getOutputStream());
            sInput = new ObjectInputStream(socket.getInputStream());
            //read the username
            username = (String) sInput.readObject();
        }catch(IOException e){} catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        for(String str:members){
            if(str.equals(username)){
                loadUserData();
                exists = true;
            }
        }
        if(!exists){
            createUserData(username);
        }
    }
    private void createUserData(String username) {
        Writer out = null;
        try{
            out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream("/home/steven/Documents/Android/MemberServerTest/" + username + ".txt" ), "utf-8"));
            out.write("\nUsername:" + username + ";Points:" + numPoints + ";Level:" + level + ";");
            System.out.println("Member data wittem for " + username);
        }catch(IOException e){}
        finally{
            try{
                out.close();
            }catch(Exception e){}
        }
    }

    private void loadUserData() {
        BufferedReader in = null;
        try{
            in = new BufferedReader(new FileReader("/home/steven/Documents/Android/MemberSeverTest/" + username +".txt"));
            String str;
            str = in.readLine();
            while(( str = in.readLine()) != null){
                properties.addAll(Arrays.asList(str.split(";")));
            }
            in.close();
        }catch(IOException e){}
        finally{
            try{
                in.close();
            }catch(Exception e){}
        }
        for(String i:properties){
            String[] me = i.split(":");
            if(me[0].equals("Username")){
                username = me[1];
            }else if(me[0].equals("Points")){
                numPoints = Integer.parseInt(me[1]);
            }else if(me[0].equals("Level")){
                level = me[1];
            }
        }
        System.out.println("Member data loaded for " + username);
    }
    public void run(){
        boolean keepGoing = true;
        while(keepGoing){
            try{
                memMes = (MemberMessage) sInput.readObject();
                if(memMes != null){
                    memMes = new MemberMessage(MemberMessage.UPDATE, this.username, this.numPoints, this.level);
                }else{
                    switch(memMes.getType()){
                    case MemberMessage.UPDATE:
                        System.out.println("Update message received from " + username);
                        this.username = memMes.getUsername();
                        this.numPoints = memMes.getNumPoints();
                        this.level = memMes.getLevel();
                        writeToMember(new MemberMessage(MemberMessage.UPDATE, this.username, this.numPoints, this.level));
                        break;
                    case MemberMessage.RECIEVED:
                        System.out.println("Received message recieved from " + username);
                        writeToMember(new MemberMessage(MemberMessage.DISCONECT, null, -1, null));
                        break;
                    case MemberMessage.DISCONECT:
                            System.out.println("Disconnecting from " + username + "...");
                            keepGoing = false;
                            break;
                    case MemberMessage.UPDATE_REQUEST:
                        display("GET request from " + username);
                        writeToMember(new MemberMessage(MemberMessage.UPDATE, this.username, this.numPoints, this.level));
                        break;
                    case 100:
                        System.out.println(memMes.getLevel());
                        MemberServer.stop();
                        break;
                    }
                }
            }catch(IOException e){keepGoing = false; display("IOException");}
            catch (ClassNotFoundException e){keepGoing = false;}
            catch(NullPointerException e){
                keepGoing = false;
                display("NullPointerException");
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        remove(id);
        close();
    }
    private void writeToMember(MemberMessage j){
        try{
            sOutput.writeObject(j);
        }catch(IOException e){
            System.out.println("Error writing to " + username);
            e.printStackTrace();
        }
    }
    // try to close everything
    private void close() {
        createUserData(username);
        // try to close the connection
        try {
            if(sOutput != null) sOutput.close();
        }
        catch(Exception e) {}
        try {
            if(sInput != null) sInput.close();
        }
        catch(Exception e) {};
        try {
            if(socket != null) socket.close();
        }
        catch (Exception e) {}
    }
}
}

现在,我看到的问题是调用sOutput.wirteObject(mh)的实际sendUpdate()方法。在服务器端,此发送对象被接收为null。服务器连接的方式是它接受套接字连接,创建一个成员对象来处理IO,然后侦听任何incomming MemberMessage对象。收到MemberMessage时会出现问题;但是,它的值为null。

任何想法? 先谢谢你的帮助!

此外,还有MemberMessage类:

/**
 * This class will define the updates to the different properties of a Member object.
 * Properties include: usename, #points, and level. 
 *
 *
 */
public class MemberMessage implements Serializable{
protected static final long serialVersionUID = 110L;
public static final int UPDATE = 0, DISCONECT = 1, RECIEVED = 2, UPDATE_REQUEST = 3;
public static final String LEVEL1 = "I'm an expert and I want to help"
        ,LEVEL2 = "I'm doind okay and I don't need help - but I'm not confident enough to help others."
        ,LEVEL3 = "I need help"
        ,LEVEL4 = "I need a tutor because I just can't get the hang of this subject.";
private String username, level;
private int numPoints;
private int type;
public MemberMessage(int type, String username, int numPoints, String level){
    this.type = type;
    this.username = username;
    this.numPoints = numPoints;
    this.level = level;
}
public String getUsername(){
    return this.username;
}
public int getNumPoints(){
    return this.numPoints;
}
public String getLevel(){
    return this.level;
}
public int getType(){
    return this.type;
}
}

1 个答案:

答案 0 :(得分:0)

你的后续编辑模糊了这个事实,确实让你的帖子毫无意义,但你得到IOException来电readObject()然后继续,好像你没有得到它,所以变量你读入仍为空。不要写这样的代码。依赖于readObject()调用成功的代码应该与调用一起位于try块中。

当你得到IOException,特别是EOFException时,你应该关闭套接字并退出读取循环。立即。不像现在那样。