【问题标题】:Server Client Socket Programming服务器客户端套接字编程
【发布时间】:2013-09-12 14:54:34
【问题描述】:

我已经建立了一个 android TCP 连接,其中服务器是用 java 编写的,客户端是用 android 编写的。它基本上是一个服务器客户端聊天。代码一切正常,运行良好。问题是,当我关闭 android 客户端时,服务器忘记了客户端并且不再检索该客户端,但服务器和客户端都需要重新启动。我希望当我关闭客户端但服务器仍在运行时再次运行客户端,然后服务器应该搜索他最近的客户端并恢复服务器客户端聊天。我正在提供我的代码。请有人帮助尽快修改我的代码。 谢谢

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);
} }

【问题讨论】:

  • “服务器应该记住客户端”是什么意思?我看不到客户端重新连接时可能会记住的代码中保存的任何内容。这一切都很简单,无状态,交流。
  • 当然,代码不包含与客户端重新连接的材料。如果您再次阅读我的问题,您会知道这是我问的;在代码中添加什么以重新连接客户端
  • 知道了。看我的回答。

标签: java android sockets


【解决方案1】:

我认为关键是您如何识别客户端,以便一旦它回来,您希望服务器能够记住它。我没有在服务器代码中看到它跟踪客户端的逻辑。

话虽如此,识别TCP客户端的一种方法是使用客户端的IP地址和端口号。如果我们关闭那个 TCP 客户端并重新启动它,客户端的端口号可能无法得到保证,因为大多数 TCP 客户端不调用 bind() 并且只是使用 connect() 来获取临时端口号。或者,您可以使用应用程序层逻辑(记住应用程序位于 TCP 之上),其中客户端可以使用唯一标识符,也可以要求服务器为其提供唯一标识符。因此,当客户端返回时,它会告诉服务器它有一个标识符并且它希望恢复该连接。这样,服务器就可以将新的 fd 与它之前发布的标识符相关联。请注意,如果服务器发布标识符,则更容易保证标识符的唯一性——例如,服务器可以增量发布标识符。

【讨论】:

  • @AqsaIffi 为什么?这不是免费的编码服务。你应该在这个职业中做你自己的工作。
  • 我提供给你的代码是我自己的作品。你更期待什么。我给了你我的代码,我只需要一些修改。如果你连这个都做不到,那我应该期待什么..
【解决方案2】:

我假设某种聊天应用程序 - 当用户在他/她的 Android 设备上点击应用程序时 - 将最后的消息显示为历史记录。

识别客户的部分是您必须从设计方面考虑的事情,考虑到数据隐私等问题。让我解释一些替代方案:

  • 通过地址识别客户:这是您可以通过client.getInetAddress().getHostAddress() 获得的字符串。由于 IP 地址可以在 DHCP 环境中重复使用,并且 Android 设备的主机名是由 Android 定义的,用户无法更改,因此这种识别方法可能是一种好方法,但不一定总是同一个客户端。如果意外识别出另一台 Android 设备并获取实际另一位用户的历史记录,您的应用会发生什么情况?
  • 您可能希望将设备的 IMEI 作为唯一标识符传输到服务器,并使用它来识别用户/应用程序。有关如何使用 getDeviceId() 的信息,请参阅 TelephonyManager
  • 通过上面的两个标识,您可以在不让用户知道的情况下识别用户/设备/应用程序,您这样做了。根据您的应用程序环境的敏感程度(例如公共德语应用程序与您的私人小助手应用程序),这可能是一个法律问题。所以,这里的出路是创建用户帐户,让用户注册、登录、使用您的应用程序和注销。然后,您可以在用户注册时签署免责声明。当然,这是迄今为止最复杂的解决方案。

最后,您需要存储消息的历史记录。我会扩展messageListener.messageReceived(message); 行和sendMessage(String message) 方法来保存消息,例如在每个客户端的文件中。

【讨论】:

  • 嗯,你尝试了什么,你得到了什么?
  • 我试图通过 IP 地址和端口号来识别客户端。但是我的程序没有任何变化。问题仍然存在。
  • 端口号不是识别客户端所必需的,因为端口是供服务器监听的。我还是不明白,你期望什么。您是否正在寻找可以复制/粘贴的代码?
  • 我已经修改了很多代码,现在我无法再修改它了。如果我现在得到一个复制/粘贴代码,那么它对我来说会更容易接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-06
  • 2013-09-29
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多