简体   繁体   English

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

[英]Server recieves message after client disconnects

In my project there is a server that sits for clients and serves them. 在我的项目中,有一个服务器可供客户使用并为其提供服务。

The server---- 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));

    }

This is in the main method, the server creates an infinite loop (thread) that will accept incoming connections. 这是在main方法中,服务器创建一个接受传入连接的无限循环(线程)。 Once a connection has been received the server will create a new Handler object that takes the client who has connected as an argument. 一旦收到连接,服务器将创建一个新的Handler对象,该对象将连接的客户端作为参数。

The Handler class 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();
        }

    }

}

In this class the main objective is to handle the clients request. 在这个类中,主要目标是处理客户端请求。 So the constructor initializes the socket object to it's owning instance. 因此构造函数将套接字对象初始化为它拥有的实例。

in the run method the objects are instantiated, and then there is an infinite loop which is suppose to print any incoming messages from clients. 在run方法中,对象被实例化,然后有一个无限循环,它假定打印来自客户端的任何传入消息。

The loop will break when the client disconnects, and this is where the close() method is called, to gracefully close and release resources. 当客户端断开连接时,循环将中断,这就是调用close()方法的地方,以便正常关闭和释放资源。 With this the thread ends. 有了这个,线程就结束了。

The Client - (Android) 客户端 - (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;
        }
    }

}

Last time I played with Android Studio was a year ago or so, and I am very positive that network/IO operations were possible to run on the main thread. 上次我玩Android Studio是在一年前左右,我非常肯定网络/ IO操作可以在主线程上运行。 But the golden rule implies to not block the main thread, and there are some blocking methods. 但黄金法则意味着不阻止主线程,并且有一些阻塞方法。

I chose to use the AsyncTask interface since it encapsulates the lower level Thread class (Easier to use/ understand the life cycle for me). 我选择使用AsyncTask接口,因为它封装了较低级别的Thread类(更容易使用/了解生命周期)。

The ConnectToServer class successfully connects to the server, but once the SendToServer class is called, the server doesn't receive the message. ConnectToServer类成功连接到服务器,但一旦调用SendToServer类,服务器就不会收到该消息。

Once I disconnect the client (terminate the app) the server then prints out the messages. 一旦我断开客户端(终止应用程序),服务器就会打印出消息。

Why is the server receiving the messages after the client disconnects? 为什么服务器在客户端断开连接后收到消息?

You're reading lines but you aren't writing lines. 你正在读行,但你不是在写行。 Add a line terminator to the message being sent, or use println() instead of write() . 在正在发送的消息中添加行终止符,或使用println()而不是write()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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