简体   繁体   中英

Server Client Socket Programming

I have established an android TCP connection in which server is written in java and client is written in android. It is basically a server client chat. The code is all fine and it runs well. The problem is that when I close the android client then the server forgets the client and does not retrieve that client again but the server and client both are needed to start again.I want that when I close the client but the server is still running and run the client again, then server should search his recent client and resume the server client chat. I'm providing my code. Kindly if some one help to modify my code as soon as possible. Thanks

TCPServer.java

import javax.swing.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
* The class extends the Thread class so we can receive and send messages at the same   time */
public class TCPServer extends Thread {

public static final int SERVERPORT = 4444;
private boolean running = false;
private PrintWriter mOut;
private OnMessageReceived messageListener;

public static void main(String[] args) {

    //opens the window where the messages will be received and sent
    ServerBoard frame = new ServerBoard();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);

}

/**
 * Constructor of the class
 * @param messageListener listens for the messages
 */
public TCPServer(OnMessageReceived messageListener) {
    this.messageListener = messageListener;
}


/**
 * Method to send the messages from server to client
 * @param message the message sent by the server
 */
public void sendMessage(String message){
    if (mOut != null && !mOut.checkError()) {
        mOut.println(message);
        mOut.flush();
    }
}

@Override
public void run() {
    super.run();

    running = true;

    try {
        System.out.println("S: Connecting...");

  //create a server socket. A server socket waits for requests to come in over network.
        ServerSocket serverSocket = new ServerSocket(SERVERPORT);


        Socket client = serverSocket.accept();
        System.out.println("S: Receiving...");

        try {

            //sends the message to the client
   mOut = new PrintWriter(new BufferedWriter(new    OutputStreamWriter(client.getOutputStream())), true);

            //read the message received from client
            BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

            //in this while we wait to receive messages from client (it's an infinite loop)
            //this while it's like a listener for messages
            while (running) {
                String message = in.readLine();

                if (message != null && messageListener != null) {
                    //call the method messageReceived from ServerBoard class
                    messageListener.messageReceived(message);
                }
            }

        } catch (Exception e) {
            System.out.println("S: Error");
            e.printStackTrace();
        } finally {
            client.close();
            System.out.println("S: Done.");
        }

    } catch (Exception e) {
        System.out.println("S: Error");
        e.printStackTrace();
    }

}


//Declare the interface. The method messageReceived(String message) will must be implemented in the ServerBoard
//class at on startServer button click
public interface OnMessageReceived {
    public void messageReceived(String message);
} }

I think the key is how do you identify a client, so that once it comes back, you expect hte server to remember it. I dont see the logic in the server code where it keeps track of the client.

Having said that, one way to identify the TCP client is to use the IP address and port number of the client. If we close that TCP client and restart it again, the port number of the client may not be guaranteed since most of hte TCP clients do not call bind() and simply use connect() to get an ephemeral port number. Or, you could use an application layer logic (remember the application sits on top of TCP), where the client can use a unique identifier or can ask the server to provide it a unique identifer. So, when the client comes back, it then tells the server that it has a identifier and it would like to resume that connection. WIth that, the server can associated the new fd with the identifier that it had issued earlier. Note that if the server issues an identifier, then it is easier to guarantee identifier uniqueness -- for example, the server could issue the identifier incrementally.

I assume some kind of chat-application that - when the user clicks on the App on his/her Android device - shows the last messages as history.

The part of identifying the client is something you have to think from the design side, considering things like data privacy. Let me explain a few alternatives:

  • Identify client by Address: This is a String you can get with client.getInetAddress().getHostAddress() . As the IP Address is something that can be reused in a DHCP environment and the hostname of an Android device is defined by Android that cannot by changed by the user, this identification method could be a good way but not necessarily always really the same client. What happens in your App, when another Android device is accidently indentified and gets the history of actually another user?
  • You might want to transfer the IMEI of the device as unique identifier to the server and use this to identify the user/App. See TelephonyManager for information how to use getDeviceId() .
  • With the two identifications above you identify the user/device/app without letting the user know, that you do so. Depending on how sensitive the environment of your App is (eg Public German App vs. your private little helper App) this can be a legal issue. So, the way out here, is to create user accounts, let the user register, login, work with your App and logout. You can then have a disclaimer that the user signs when he/she registers. Of course this is by far the most complex solution.

In the end you need to store the history of messages. I would expand the line messageListener.messageReceived(message); and the method sendMessage(String message) to save the messages, for example in a file for each client.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM