Android 开发:通信篇-TCP客户端

这节教给大家用Android写一个TCP客户端程序

官方文档

Socket - Android SDK | Android Developers

 


页面


编写连接程序

1.获取控件

    EditText editTextIPAddress,editTextPort;//输入IP地址,端口号
    Button buttonConnect;//连接按钮

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buttonConnect = findViewById(R.id.buttonConnect);
        editTextIPAddress = findViewById(R.id.editTextIPAddress);
        editTextPort = findViewById(R.id.editTextPort);


    }

2.添加网络权限

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

3.定义一个socket

Socket socket;

4.编写按钮点击连接/断开程序

MyHandler myHandler;//使用Handler更新控件

myHandler = new MyHandler();

        buttonConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (buttonConnect.getText()=="连接"){
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                            try{
                                socket = new Socket(editTextIPAddress.getText().toString(),Integer.valueOf(editTextPort.getText().toString()));
                                if(socket.isConnected()){
                                    msg.what = 1;//设置消息变量的 what 变量值 为1
                                }
                            }catch (Exception e){
                                msg.what = 0;//设置消息变量的 what 变量值 为0
                            }
                            myHandler.sendMessage(msg);//插入消息队列
                        }
                    }).start();
                }
                else{
                    try{ socket.close(); }catch (Exception e){} //关闭连接
                    buttonConnect.setText("连接");//按钮显示连接
                }
            }
        });

//Handler
    class MyHandler extends Handler {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    Toast.makeText(MainActivity.this,"连接出错",Toast.LENGTH_SHORT).show();
                    break;
                case 1:
                    buttonConnect.setText("断开");//按钮显示断开
                    break;
                default: break;
            }
        }
    }

提示:获取IP地址和端口号,执行连接

socket = new Socket(editTextIPAddress.getText().toString(),Integer.valueOf(editTextPort.getText().toString()));

当前程序

    EditText editTextIPAddress,editTextPort;//输入IP地址,端口号
    Button buttonConnect;//连接按钮
    Socket socket;

    MyHandler myHandler;//使用Handler更新控件
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myHandler = new MyHandler();
        buttonConnect = findViewById(R.id.buttonConnect);
        buttonConnect.setText("连接");
        editTextIPAddress = findViewById(R.id.editTextIPAddress);
        editTextPort = findViewById(R.id.editTextPort);

        buttonConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (buttonConnect.getText()=="连接"){
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                            try{
                                socket = new Socket(editTextIPAddress.getText().toString(),Integer.valueOf(editTextPort.getText().toString()));
                                if(socket.isConnected()){
                                    msg.what = 1;//设置消息变量的 what 变量值 为1
                                }
                            }catch (Exception e){
                                msg.what = 0;//设置消息变量的 what 变量值 为0
                            }
                            myHandler.sendMessage(msg);//插入消息队列
                        }
                    }).start();
                }
                else{
                    try{ socket.close(); }catch (Exception e){} //关闭连接
                    buttonConnect.setText("连接");//按钮显示连接
                }
            }
        });
    }

    //Handler
    class MyHandler extends Handler {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    Toast.makeText(MainActivity.this,"连接出错",Toast.LENGTH_SHORT).show();
                    break;
                case 1:
                    buttonConnect.setText("断开");//按钮显示断开
                    break;
                default: break;
            }
        }
    }


接收数据

1.定义 InputStream 用于获取数据输入流,定义一个数组用于缓存数据

InputStream inputStream;//获取输入流

byte[] RevBuff = new byte[1460];//缓存数据

2.定义一个函数,里面放一个任务,用于不停的接收数据

public void Recv(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (socket!= null && socket.isConnected()){
                    try{
                        int Len = inputStream.read(RevBuff);//获取数据
                        if(Len!=-1){
                            Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                            msg.what = 3;//设置消息变量的 what 变量值 为3
                            msg.arg1 = Len;//接收的数据个数
                            msg.obj = RevBuff;//传递数据
                            myHandler.sendMessage(msg);//插入消息队列
                        }
                        else{//连接异常断开
                            Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                            msg.what = 0;//设置消息变量的 what 变量值 为0
                            myHandler.sendMessage(msg);//插入消息队列
                            break;
                        }
                    }catch (Exception e){//连接异常断开
                        Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                        msg.what = 0;//设置消息变量的 what 变量值 为0
                        myHandler.sendMessage(msg);//插入消息队列
                        break;
                    }
                }
            }
        }).start();
    }

3.调用接收函数

4.在Handle中处理数据,把数据显示在页面

4.1.获取控件

4.2.把接收的消息追加到Textview显示


测试

1.电脑端开启TCP服务器

2.保证手机和电脑在一个局域网内

查看自己的电脑IP

3.手机连接


接收显示16进制数据

1.关于16进制显示和前面的串口上位机显示16进制数据是一样的道理

C#开发: 通信篇-串口调试助手 - 杨奉武 - 博客园

2.JAVA和C#提供的函数不一样,java的转换程序如下:

    /**
     * 16进制byte转16进制String--用空格隔开
     * @param bytes
     * @return
     */
    public static String byteToHexStr(byte[] bytes)
    {    
        String str_msg = "";
        for (int i = 0; i < bytes.length; i++){    
            str_msg = str_msg + String.format("%02X",bytes[i])+" ";
        }    
        return str_msg;    
    }  

3.获取16进制选择控件

4.编写处理函数


测试


清除接收


发送数据

1.获取控件,定义输出流变量

2.获取输出流

3.点击发送按钮发送发送文本框里面的数据

4.测试

 


发送16进制数据

1.文本框里面输入的是字符串

假设输入的是 55FD

那么获取的是 "55FD"

需要转换为 0x55  0xFD

获取第一个字符 5    hexString.charAt(0)

转换为 16进制形式  Character.digit(hexString.charAt(0), 16)

获取第二个字符5     hexString.charAt(1)

转换为 16进制形式  Character.digit(hexString.charAt(1), 16)

然后组合成一个16进制

byte data =  (byte) ((Character.digit(hexString.charAt(0), 16) << 4) + Character.digit(hexString.charAt(1), 16))

2.完整的程序如下

/***
     *"2B44EFD9" --> byte[]{0x2B, 0x44, 0xEF,0xD9}
     * @param hexString
     * @return
     */
    public static byte[] hexStringToByteArray(String hexString) {
        StringBuilder sb = null;
        hexString = hexString.replaceAll(" ", "");

        if ((hexString.length()%2)!=0) {//数据不是偶数
            sb = new StringBuilder(hexString);//构造一个StringBuilder对象
            sb.insert(hexString.length()-1, "0");//插入指定的字符串
            hexString = sb.toString();
        }

        int len = hexString.length();
        byte[] bytes = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            if ((
                    (hexString.charAt(i)>='0' && hexString.charAt(i)<='9') ||
                    (hexString.charAt(i)>='A' && hexString.charAt(i)<='F') ||
                    (hexString.charAt(i)>='a' && hexString.charAt(i)<='f')
             )&&
                    (hexString.charAt(i+1)>='0' && hexString.charAt(i+1)<='9') ||
                    (hexString.charAt(i+1)>='A' && hexString.charAt(i+1)<='F') ||
                    (hexString.charAt(i+1)>='a' && hexString.charAt(i+1)<='f')){
                // 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个字节
                bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
                        .digit(hexString.charAt(i+1), 16));
            }
            else return null;
        }
        return bytes;
    }

3.获取控件

4.编写处理程序

5.测试


补充

让输入的内容默认显示在左上角

android:gravity="top"

转载于:Android 开发: 通信篇-TCP客户端 - 杨奉武 - 博客园 

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Smack是一个开源的XMPP客户端库,可用于在Android平台上构建即时通信应用程序。在使用Smack的Android应用程序中,需要使用Smack-Android库来处理网络和连接管理。 以下是一个简单的示例代码,演示如何使用Smack-Android库连接到XMPP服务器并发送消息: 1. 添加依赖库 在项目的build.gradle文件中添加以下依赖: ``` dependencies { implementation 'org.igniterealtime.smack:smack-android-extensions:4.4.0' implementation 'org.igniterealtime.smack:smack-tcp:4.4.0' } ``` 2. 初始化连接 在应用程序启动时,需要初始化XMPPConnection对象,并且连接到XMPP服务器。 ``` XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder() .setUsernameAndPassword("username", "password") .setXmppDomain("example.com") .setHost("xmpp.example.com") .setPort(5222) .setSecurityMode(ConnectionConfiguration.SecurityMode.required) .build(); XMPPTCPConnection connection = new XMPPTCPConnection(config); try { connection.connect(); connection.login(); // Connection successful } catch (SmackException | IOException | XMPPException e) { e.printStackTrace(); // Connection failed } ``` 3. 发送消息 连接成功后,可以使用XMPPConnection对象发送消息。 ``` ChatManager chatManager = ChatManager.getInstanceFor(connection); Chat chat = chatManager.createChat("recipient@example.com"); try { chat.sendMessage("Hello, World!"); } catch (SmackException.NotConnectedException | InterruptedException e) { e.printStackTrace(); } ``` 这是一个简单的Smack-Android示例,用于连接到XMPP服务器并发送消息。当然,在实际应用程序中可能需要更多的功能和处理,但这个示例提供了一个入门的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值