客户端断开连接后,服务器收到消息

时间:2016-04-06 04:07:51

标签: java android multithreading sockets android-asynctask

在我的项目中,有一个服务器可供客户使用并为其提供服务。

服务器---- Main

    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对象,该对象将连接的客户端作为参数。

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接口,因为它封装了较低级Thread类(更容易使用/了解我的生命周期)。

ConnectToServer类成功连接到服务器,但是一旦调用SendToServer类,服务器就不会收到该消息。

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

为什么服务器在客户端断开连接后收到消息?

1 个答案:

答案 0 :(得分:2)

你正在读行,但你不是在写行。在正在发送的邮件中添加行终止符,或使用public class Test { public static void main(String[] args) { int list[] = {1, 2, 3, 4, 5, 6}; for (int i = 1; i < list.length; i++) { System.out.println("\n\n\nloop number " + i); System.out.println("\ni = " + i); System.out.println("\nThe value at list[i] = " + list[i]); System.out.println("\ni - 1 = " + (i - 1)); System.out.println("\nSo I'm accessing element " + (i - 1) + " in the list for this iteration."); System.out.println("\nThe value at list[i - 1] = " + list[i - 1]); System.out.println("\nEnd of loop " + i); list[i] = list[i - 1]; } for (int i = 0; i < list.length; i++) System.out.print(list[i] + " "); } } 代替println()