安卓中用TCP跨进程通信

时间:2022-12-17 22:42:20

首先,网络操作一定不能在主线程里操作,这和修改UI是相反的,修改UI一定要在主线程里。

服务端:

1.开启一个服务,在服务里开启线程来操作网络;

2.创建ServerSocket,制定本地地址的监听接口;

3.使用ServerSocket.accept获得客户端的Socket;

4.在while里再开启线程,再在里面用Socket创建读取和写入的流工具;

5.再创建一个while,持续地读取socket里的内容,实现监听;

6.循环结束时,比如客户端断开,或服务端断开,关闭流工具,关闭Socket。


客户端:

1.创建线程,在线程里创建套接字Socket,指明要访问的服务器地址;

2.在线程里创建读取和输入流工具;

3.创建while,在循环里持续读取socket里的数据,实现监听;(1-3在同一线程内完成,第三步也可以单独开线程完成,推荐顺便写在一个线程里)

4.用户选择发送数据,创建线程发送;

5.退出时关闭socket,流工具。


相关问题:

当线程或者服务处理完相关事物后需要更改UI,可以通过异步或者发送广播来让主线程更新UI。


可以通过设置标记位来防止重复请求连接和监听连接状态。


记得服务也是跑在主线程里的;服务端可以持续监听来自客户端的信息,却没有办法持续监听自己的输出,自己返回给客户端的信息必须是即时开始,即时结束。


流工具:

BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));


PrintWriter pw = new PrintWriter(new BufferedReader(new OutputStreamWriter(socket.getOutputStream())),true); 第二个参数是自动flush


其实套接字也可以实现跨设备通信,只是对于获得设备的IP地址比较复杂,设备的IP地址和类型是会改变的,而且有些安卓系统经过厂商的改造后,IP地址不好获得,所以还是使用创建一个服务器来代理数据的传输比较好用。


获得设备地址的代码:

public static String getIPAddress(Context context){
        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);        NetworkInfo info = cm.getActiveNetworkInfo();        if (info != null && info.isConnected()){            if (info.getType() == ConnectivityManager.TYPE_MOBILE){  //移动网路                try {                    for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {                        NetworkInterface intf = en.nextElement();                        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {                            InetAddress inetAddress = enumIpAddr.nextElement();                            if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {                                return inetAddress.getHostAddress();                            }                        }                    }                }catch (SocketException e){                    e.printStackTrace();                }            }        }else if (info.getType() == ConnectivityManager.TYPE_WIFI){            WifiManager wifiMananger = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);            WifiInfo wifiInfo = wifiMananger.getConnectionInfo();            String ipAddress = intIP2StringIP(wifiInfo.getIpAddress());            return ipAddress;        }else {            Toast.makeText(context,"没有网络可用",Toast.LENGTH_LONG);        }        return null;    }    public static String intIP2StringIP(int ip) {        return (ip & 0xFF) + "." +                ((ip >> 8) & 0xFF) + "." +                ((ip >> 16) & 0xFF) + "." +                (ip >> 24 & 0xFF);    }