小编典典

关闭客户端后,Android TCP Server仅显示来自Python客户端的消息

java

我正在使用一些示例代码,该代码使我可以将消息从Python客户端发送到Android服务器(TCP)。但是,仅在关闭客户端后,该消息才会显示在Android仿真器上。

我可能缺少tcp套接字(首​​次使用和实现)背后的一些基本知识。

我的主要目的是使Android
App中的按钮可以在单击时将不同的消息发送到单独的Linux系统上的Python客户端,并且Python客户端在收到该消息后会发送回确认。

以下是我的代码

服务器.java

package test.server2;



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

public class Server {
    MainActivity activity;
    ServerSocket serverSocket;
    String message = "";
    static final int socketServerPORT = 8080;

    public Server(MainActivity activity) {
        this.activity = activity;
        Thread socketServerThread = new Thread(new SocketServerThread());
        socketServerThread.start();
    }

    public int getPort() {
        return socketServerPORT;
    }

    public void onDestroy() {
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private class SocketServerThread extends Thread {

        int count = 0;

        @Override
        public void run() {
            try {
                // create ServerSocket using specified port
                serverSocket = new ServerSocket(socketServerPORT);

                while (true) {
                    // block the call until connection is created and return
                    // Socket object
                    Socket socket = serverSocket.accept();
                    count++;


                    InputStream message2 = socket.getInputStream();
                    final String messageReceived = convertToString(message2);

                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            activity.msg.setText(messageReceived);
                        }
                    });


                    //SocketServerReplyThread socketServerReplyThread =
                      //      new SocketServerReplyThread(socket, count);
                    //socketServerReplyThread.run();

                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                message += "Something wrong! " + e.toString() + "\n";
            }
            activity.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    activity.msg.setText(message);
                }
            });
        }
    }

    private class SocketServerReplyThread extends Thread {

        private Socket hostThreadSocket;
        int cnt;

        SocketServerReplyThread(Socket socket, int c) {
            hostThreadSocket = socket;
            cnt = c;
        }

        @Override
        public void run() {
            OutputStream outputStream;
            String msgReply = "Hello from Server, you are #" + cnt;

            try {
                outputStream = hostThreadSocket.getOutputStream();
                PrintStream printStream = new PrintStream(outputStream);
                printStream.print(msgReply);
                printStream.close();

                message += "replayed: " + msgReply + "\n";

                activity.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        activity.msg.setText(message);
                    }
                });


            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                message += "Something wrong! " + e.toString() + "\n";
            }

            activity.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    activity.msg.setText(message);
                }
            });
        }

    }

    private String convertToString(InputStream message) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(message));
        StringBuilder stringbuilder = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                //stringbuilder.append(line).append('\n');
                stringbuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                message.close();
                //reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return stringbuilder.toString();
    }

    public String getIpAddress() {
        String ip = "";
        try {
            Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
                    .getNetworkInterfaces();
            while (enumNetworkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = enumNetworkInterfaces
                        .nextElement();
                Enumeration<InetAddress> enumInetAddress = networkInterface
                        .getInetAddresses();
                while (enumInetAddress.hasMoreElements()) {
                    InetAddress inetAddress = enumInetAddress
                            .nextElement();

                    if (inetAddress.isSiteLocalAddress()) {
                        ip += "Server running at : "
                                + inetAddress.getHostAddress();
                    }
                }
            }

        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ip += "Something Wrong! " + e.toString() + "\n";
        }
        return ip;
    }
}

我已将对SocketServerReplyThread的调用及相关内容注释掉了,因为这导致了错误。注释掉该内容会导致从Python客户端接收消息,但是只有在关闭客户端套接字后,它才会显示在Android仿真器上。我希望它是连续的,以便每当客户端发送一条消息(并且android服务器正在侦听)时,该消息就会被打印出来。

MainActivity.java

package test2.server;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    Server server;
    TextView infoip, msg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();


            }
        });

        infoip = (TextView) findViewById(R.id.infoip);
        msg = (TextView) findViewById(R.id.msg);
        server = new Server(this);
        infoip.setText(server.getIpAddress() + ":" + server.getPort());

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        server.onDestroy();


    }
}

Python客户端

#!/usr/bin/python

import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = "127.0.0.1" 
port = 4534
s.connect((host, port))


s.send("Thank you for connecting" + '\n')
time.sleep(10) #added to check if it gets displayed before closing or not
s.close()

阅读 306

收藏
2020-11-23

共1个答案

小编典典

默认情况下,套接字阻止。因此,当您调用readline时,在关闭套接字之前,它将永远不会返回null。按照编码,您的代码将等待,直到从客户端读取了所有数据并且客户端关闭了连接,然后将其变成1个大字符串并从convertToString返回。您需要重新配置,以便处理每个readline调用的结果并显示它,而不是将所有内容都视为1个巨型字符串。

2020-11-23