java - 服务器在客户端断开连接后收到消息

标签 java android multithreading sockets android-asynctask

在我的项目中有一个服务器为客户服务。

服务器----主

    ss = new ServerSocket(12345);
    System.out.println("Server started..");
    while(true)
    {
        System.out.println("Waiting For clients...");
        Socket client = ss.accept();
        System.out.println("Got client...");
        Thread t = new Thread(new Handler(client));
        t.start();
        //exe.execute(new Handler(client));

    }

这是在 main 方法中,服务器创建一个无限循环(线程)来接受传入的连接。一旦收到连接,服务器将创建一个新的 Handler 对象,该对象将已连接的客户端作为参数。

处理程序类

    public class Handler implements Runnable {

    Socket client;

    public Handler(Socket client) {
        // TODO Auto-generated method stub
        this.client = client;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        //streams 
        try {
            OutputStream out = client.getOutputStream();
            PrintWriter writer = new PrintWriter(out);

            InputStream in = client.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            String s = null;

            while((s=reader.readLine())!=null)
            {

                //will switch on string or convert to json object
                System.out.println("Recieved: " + s);
            }
            writer.close();
            reader.close();
            client.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

在这个类中,主要目标是处理客户端请求。因此构造函数将套接字对象初始化为其拥有的实例。

在 run 方法中,对象被实例化,然后有一个无限循环,它假设打印来自客户端的任何传入消息。

当客户端断开连接时,循环将中断,这就是 close() 的地方 方法被调用,优雅地关闭和释放资源。至此,线程结束。

客户端-(Android)

    public class MainActivity extends AppCompatActivity {

    final String ip = "192.168.0.18";
    final int port = 12345;
    Socket client;
    OutputStream out;
    PrintWriter writer;

    InputStream in;
    BufferedReader reader;
    final String TAG = "Debug: ";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new ConnectToServer().execute();
        new SendToServer().execute();


    }

    class ConnectToServer extends AsyncTask<Void, Void, Void>
    {

        @Override
        protected Void doInBackground(Void... params)
        {
            try {
                client = new Socket(ip,port);
                //Log.d(TAG, "doInBackground: connected to server");
                //set streams
                out = client.getOutputStream();
                writer = new PrintWriter(out);

                in = client.getInputStream();
                reader = new BufferedReader(new InputStreamReader(in));

                Log.d(TAG, "doInBackground: Sent");



            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    class SendToServer extends AsyncTask<Void, Void, Void>
    {

        @Override
        protected Void doInBackground(Void... params) {
            writer.write("lol");
            writer.flush();
            return null;
        }
    }

}

我上次使用 Android Studio 是在大约一年前,我非常肯定网络/IO 操作可以在主线程上运行。但是黄金法则意味着不要阻塞主线程,并且有一些阻塞方法。

我选择使用 AsyncTask 接口(interface),因为它封装了较低级别的 Thread 类(对我来说更易于使用/理解生命周期)。

ConnectToServer 类成功连接到服务器,但是调用SendToServer 类后,服务器收不到消息。

一旦我断开客户端(终止应用程序),服务器就会打印出消息。

为什么客户端断开连接后,服务端还能收到消息?

最佳答案

您正在阅读台词,但不是在写台词。在发送的消息中添加行终止符,或使用 println() 代替 write()

关于java - 服务器在客户端断开连接后收到消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36441324/

相关文章:

java - 检查客户的诚信度

java - 如何配置 ConfluenceRegistry 以使用不同的 Avro 架构源?

android - 使用 jackson 在android中使用相同的 key 但不同类型反序列化json

java.lang.RuntimeException : Can't create handler inside thread that has not called Looper. prepare() 为什么?

c++ - 多线程使用者使用boost ringbuffer不产生与输入相同的输出

java - 为什么对于较大的数字,平方根计算速度较慢?

java - 使用 finishActivity() 时的请求代码是什么

c++ - GCC:简单继承测试失败

android - 我想修改 EDITTEXT 的焦点, performAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS) 总是在 editText 上返回 false

c# - 监控许多网页/RSS 提要