安卓前端和C#后端tcp通信

635 阅读2分钟

源码链接

链接:pan.baidu.com/s/1o3cZP-fT… 提取码:0spl

安卓端代码注意事项

1. 注意要获取网络权限

在app/src/main/AndroidManifest.xml文件中

<uses-permission android:name="android.permission.INTERNET"/>

2. 添加jar包

所用jar包下载链接:

链接:pan.baidu.com/s/1gN-RwtaU… 提取码:tur4

AS3.4添加jar包方式:

  • 复制到App/libs目录下
  • 右键jar包,点击Add as library,然后等待重新build成功后即可

3.代码运行逻辑

第一步onCreate中开启一个线程,打开连接

Thread anOpenConnectionThread = new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    try
                    {
                        openConnection();
                    }
                    catch (Exception err)
                    {
                        EneterTrace.error("Open connection failed.", err);
                    }
                }
            });
 anOpenConnectionThread.start();

第二步,点击按钮后触发响应事件onSendRequest(v),发送数据

private OnClickListener myOnSendRequestClickHandler = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            onSendRequest(v);
        }
    };

4. 代码的几个关键地方

第一处,连接url设置于下方代码处,根据实际修改

private void openConnection() throws Exception
    {
        // Create sender sending MyRequest and as a response receiving MyResponse
        IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
        mySender = aSenderFactory.createDuplexTypedMessageSender(MyResponse.class, MyRequest.class);
        
        // Subscribe to receive response messages.
        mySender.responseReceived().subscribe(myOnResponseHandler);
        
        // Create TCP messaging for the communication.
        // Note: 10.0.2.2 is a special alias to the loopback (127.0.0.1)
        //       on the development machine.
        IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
        IDuplexOutputChannel anOutputChannel
            = aMessaging.createDuplexOutputChannel("tcp://192.168.43.156:8040/");
        
        // Attach the output channel to the sender and be able to send
        // messages and receive responses.
        mySender.attachDuplexOutputChannel(anOutputChannel);
    }

第二处,接收到后端返回数据加以处理的代码逻辑在此处

private void onResponseReceived(Object sender,
                                    final TypedResponseReceivedEventArgs<MyResponse> e)
    {
        // Display the result - returned number of characters.
        // Note: Marshal displaying to the correct UI thread.
        myRefresh.post(new Runnable()
            {
                @Override
                public void run()
                {
                    myResponseEditText.setText((e.getResponseMessage().Length));
                }
            });
    }

5. 自己封装时候遇到的坑

因为流程分两步,即打开连接、传输数据。分别开了两个线程,如果不需要按钮触发而是自动直接完成,需要将

onSendRequest(v) 写到如下位置,才不会因为线程执行顺序问题出错。

mySender.attachDuplexOutputChannel(anOutputChannel);
onSendRequest(v);


后端代码注意事项

1. 接收和返回数据类型定义要和前端完全相同,见如下代码

前端数据类型定义:

public static class MyRequest
    {
        public String Text;
    }

    // Response message type
    // The message must have the same name as declared in the service.
    // Also, if the message is the inner class, then it must be static.
    public static class MyResponse
    {
        public String Length;
    }


后端数据类型定义:

// Request message type
    public class MyRequest
    {
        public string Text { get; set; }
    }

    // Response message type
    public class MyResponse
    {
        public int Length { get; set; }
    }

2. 前端channel和后端channel要完全相同

均为如下代码

IDuplexOutputChannel anOutputChannel
            = aMessaging.createDuplexOutputChannel("tcp://192.168.43.156:8040/");

3. 后端接收和返回数据代码如下

private static void OnMessageReceived(object sender, TypedRequestReceivedEventArgs<MyRequest> e)
        {
            Console.WriteLine("Received: " + e.RequestMessage.Text);

            // Create the response message.
            MyResponse aResponse = new MyResponse();
            aResponse.Length = e.RequestMessage.Text.Length;

            // Send the response message back to the client.
            myReceiver.SendResponseMessage(e.ResponseReceiverId, aResponse);
        }