Android端Socket服务器

/** * Created by Jack Stone on 2016/11/17. * Socket服务器,PC可以通过USB连接、ADB端口映射连接本服务器,不需要通过Wifi和网络 */public class TCPConnect implements Runnable {    private static final String TAG = "TCPConnect";    private final int SERVER_PORT = 10086;    private ServerSocket mServerSocket;    private Socket mClient;    private Callback callback;    public TCPConnect(Callback callback) {        this.callback = callback;    }    @Override    public void run() {        try {            String ip = InetAddress.getLocalHost().getHostAddress();            mServerSocket = new ServerSocket(SERVER_PORT);            callback.call("建立服务器:[" + ip + ":" + SERVER_PORT + "]");        } catch (IOException e) {            callback.call("建立服务器异常:" + e.getMessage());        }        while (true) {            BufferedOutputStream out = null;            BufferedReader in = null;            try {                mClient = mServerSocket.accept();                callback.call("建立链接:" + mClient.getInetAddress().toString() + ":" + mClient.getPort());                out = new BufferedOutputStream(mClient.getOutputStream());                in = new BufferedReader(new InputStreamReader(mClient.getInputStream()));                String request = receive(in);                callback.call("client:"+request);                send(out, request);            } catch (IOException e) {                Log.e(TAG, "run: ", e);                callback.call(e.getMessage());            } finally {                close(out);                close(in);                close(mClient);            }        }    }    private void send(OutputStream out, String msg) throws IOException {        msg += "\n";        out.write(msg.getBytes("utf-8"));    }    private String receive(BufferedReader in) throws IOException {        String r = in.readLine();        callback.call("origin request:"+r);        if(r.contains("\\&")) {            callback.call("进行\\&替换!");            r = r.replaceAll("\\\\&","\n");        }        return r;    }    private void close(OutputStream out) {        if (out != null) {            try {                out.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    private void close(BufferedReader in) {        if (in != null) {            try {                in.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    private void close(Socket socket) {        if (socket != null) {            try {                socket.close();            } catch (IOException e) {                Log.e(TAG, "run: ", e);            }        }    }    public interface Callback {        void call(String msg);    }}

PC客户端

using CMDExecutor;using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Text.RegularExpressions;namespace AndroidUSBSocket{    public class SocketClient    {        public const string LOCAL_PORT = "12580";        public SocketClient(string adb_path, string remote_port)        {            AdbExecutor adb = AdbExecutor.GetInstance(adb_path);            adb.Forward(LOCAL_PORT, remote_port);        }        public string Request(string msg)        {            Socket client = null;            try            {                client = create();                connect(client, LOCAL_PORT);                if (client.Connected)                {                    send(client, msg);                    return receive(client);                }                else                {                    return "连接失败!";                }            }            catch(Exception e)            {                return $"Error:{e.Message}";            }            finally            {                client.Shutdown(SocketShutdown.Both);                client?.Close();                Request(msg);            }        }        private static void connect(Socket socket,string port)        {            IPAddress myIP = IPAddress.Parse("127.0.0.1");            IPEndPoint EPhost = new IPEndPoint(myIP, int.Parse(port));            socket.Connect(EPhost);     //create connection        }        private static Socket create()        {            return new Socket(                    AddressFamily.InterNetwork,                    SocketType.Stream,                    ProtocolType.Tcp);        }        private static void send(Socket socket, string msg)        {            //request            msg = msg.Replace("\n", "\\&");                 //replace all '\n' to '\&', those will be replace to '\n' when server received this msg            msg += "\n";                                    //server is using readLine(), if not send a '\n' the stream won't push data to server            byte[] data = Encoding.UTF8.GetBytes(msg);            socket.Send(data);                              //send message to server            //socket.Shutdown(SocketShutdown.Send);         //N-E-V-E-R close output stream, the socket will be closed together            Debug.WriteLine($"发送完毕(长度[{msg.Length}] 字节[{data.Length}]):\n{msg}");        }        private static string receive(Socket socket)        {            //get response            string str = "";            byte[] data = new byte[10240];            int len = 0;            int i = 0;            while ((i = socket.Receive(data)) != 0)         //read response string            {                len += i;                string piece = Encoding.UTF8.GetString(data, 0, i);                str += piece;            }            Debug.WriteLine($"接收完毕(长度[{str.Length}] 字节[{len}]):\n{str}");            return str;        }    }}



使用ADB进行端口的映射转发:adb forward tcp:local_port tcp:remote_port

SocketClient构造中的ADBExecutor就是用来执行这个命令的


另外有一点不明白的是 SocketClient的receive方法中,byte[]的size我定的是10240

因为如果定小了,在获取字符串的过程中就会因为这个尺寸不合适导致在边界上的字符变成???

C#不是很熟悉,这个地方不知道该怎么做,索性把size定得大一点,一般用不了这么长的字节数组


使用这个方法要注意的是,只能通过PC主动向Android端发起请求,看了很多文档,貌似Android端是不能主动请求PC的,这个好像跟ADB的机制有关

但是ADB我并不是理解得特别清楚,所以如果有大神知道如何让Android端主动请求PC端的服务器的话,希望不吝赐教!


有一个帖子说,Android通过USB连接电脑后,默认电脑的IP就是10.0.2.2,我试了一下,没啥成果,如果有人成功请联系我。


其他需要注意的地方在代码中的注释我都清楚地写出来了,欢迎交流。


更多相关文章

  1. Android中限制EditText(输入框)文字输入长度
  2. Android之HttpPost与HttpGet使用
  3. android上传图片或文件
  4. 如何保证手机端的app访问web服务器的安全
  5. android和PC(Python)通过USB(adb模式)基于Socket传输图像(视频)
  6. android上传文件至服务器(android端+服务器端)
  7. [置顶] Android(安卓)错误信息捕获发送至服务器
  8. Android(安卓)网星工具箱Beta版
  9. Android(安卓)MediaCodec 解码H264码流播放

随机推荐

  1. 既然android service是运行在主线程中的,
  2. Json解析(GSON开源库——最简单的json解析
  3. android 应用程序意见反馈
  4. Android筆記
  5. .NET开源了,Visual Studio开始支持 Androi
  6. 报告称Android和iOS设备正慢慢侵蚀PC市场
  7. Android登录界面的实现代码分享
  8. Android中OnkeyDown事件和OnBackPressed
  9. Android中使用GPS和NetWork获取定位信息
  10. java/android 设计模式学习笔记(5)---对象