专栏首页Linux驱动15.Android-实现TCP客户端,支持读写

15.Android-实现TCP客户端,支持读写

在上章14.Android-使用sendMessage线程之间通信我们学习了如何在线程之间发送数据.

接下来我们便来学习如何通过socket读写TCP.

需要注意的是socket必须写在子线程中,不能在ui主线程中直接使用,所以我们这里创建了两个class:

MainActivity(主界面)、TcpThread(获取socket接收的数据)

由于代码有注释了,所以就不解释了.

1.gif效果如下

2.activity_main.xml如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    
    <EditText 
        android:id="@+id/et_text"
        android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_alignParentTop="true"
        android:hint="请填入要发送的内容"
        />
    
     <Button 
        android:id="@+id/btn_send"
        android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_alignParentRight="true"
           android:layout_below="@+id/et_text"
        android:text="发送"
        />
     
     <TextView 
         android:id="@+id/tv_recv"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_below="@+id/btn_send"
         android:minLines="20"
         android:hint="接收的内容"
         />
</RelativeLayout>

3.MainActivity.java如下所示

package com.example.tcpdemo;


import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    TcpThread mt;
    
    TextView tv_recv;
    EditText et_text;        //要发送的内容
    Button    btn_send;
    
    //定义一个handler
    public Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            //打印服务器端发来的消息
            System.out.println("read:"+msg.obj.toString());
            tv_recv.append(msg.obj.toString()+"\r\n");
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        tv_recv =  (TextView)findViewById(R.id.tv_recv);
        et_text =  (EditText)findViewById(R.id.et_text);
        
        
        mt = new TcpThread();
        mt.setHandler(mHandler);    //设置handler
        mt.setIp("10.10.10.104");   //设置服务器地址
        mt.start();                    //启动线程
        
        
        btn_send =  (Button)findViewById(R.id.btn_send);
        
        btn_send.setOnClickListener(new OnClickListener() {
            
            //向服务器端发送数据
            public void onClick(View v) {
                
                if(!mt.write(et_text.getText().toString()))
                {
                    Toast.makeText(getApplicationContext(), "发送失败", Toast.LENGTH_SHORT).show();
                    
                }
            }
        });
    }
}

4.TcpThread.java如下所示

package com.example.tcpdemo;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.Handler;
import android.os.Message;

public class TcpThread extends Thread {
    
        
        Handler mHandler=null; 
        Socket socket = null;
        String ip = null;
        OutputStream outputStream = null;        //输出流
        InputStream inputStream=null;            //接收流
        //获取另一个线程的Handler
        public void setHandler( Handler handler){
            mHandler = handler;
        }
        
        //设置服务器IP
        public void setIp(String ip){
            this.ip = ip;
        }
                
        public void run(){
           
          try {
                    socket = new Socket(ip, 8080);        //访问指定的ip地址:8080
                } catch (UnknownHostException e) { 
                    e.printStackTrace();
                } catch (IOException e) { 
                    e.printStackTrace();
                }
                
         
           //获取输出流
            try {
                outputStream = socket.getOutputStream();
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }    
            try{
                while (true)         //读取服务器端发送来的数据
                {
                    final byte[] buffer = new byte[1024];//创建接收缓冲区
                    inputStream = socket.getInputStream();
                    final int len = inputStream.read(buffer);//数据读出来,并且返回数据的长度
                    if(len>0)
                    {
                         Message msg = mHandler.obtainMessage(); 
                         //设置发送的内容
                         msg.obj = new String(buffer,0,len); 
                         mHandler.sendMessage(msg);  
                    }
                    
                }
            }
            catch (IOException e) {
                
            }
            
        }
        
        //向服务器端写入数据
        public boolean write(String text){
            
            boolean ret = true;
            try {
                outputStream.write(text.toString().getBytes());
            } catch (IOException e) { 
                ret = false;
                e.printStackTrace();
            }
            return ret;
        }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 6.Android-五大布局

    如果要想设置两个控件的比例大小,则设置android:layout_weight(不是android:layout_width),值越大则比例越大(垂直布局则设...

    张诺谦
  • 5.Android-电话拨号器详解

    之前学习了3.Android-ADT之helloworld项目结构介绍后,本章便来写个简单的电话拨号器程序.

    张诺谦
  • 13.Android-ListView使用、BaseAdapter/ArrayAdapter/SimpleAdapter适配器使用

    ListView 是 Android 系统为我们提供的一种列表显示的一种控件,使用它可以用来显示我们常见的列表形式。继承自抽象类 AdapterView。继承图...

    张诺谦
  • 滑动吸顶效果

    需求是先滑动里面的列表,滑动到一个位置时外面滑动,外面滑动一段距离后再里面滑动。最初想用 CoordinatorLayout 加 RecyclerView,但效...

    七适散人
  • Android 天气APP(二十九)壁纸设置、图片查看、图片保存

      最近收到一些用户的反馈,内容是背景更换这个功能用的不是很舒服,至于为什么不舒服,说不上来。之前我是奔着功能实现去做的,所以很多的细节并没有想的太多,思虑再三...

    晨曦_LLW
  • 多功能时钟应用

    提莫队长
  • A020-列表容器之ListView

    前面介绍了Android UI中的五大布局容器,本节课介绍实际项目当中经常会用到的组件-ListView,它也是一个布局容器,它的每一项就是我们的列表项,每一个...

    用户1130025
  • Android 天气APP(二十)增加欢迎页及白屏黑屏处理、展示世界国家/地区的城市数据

    本来这一篇文章应该和上一篇放到一起的,但是考虑到篇幅的问题,我就分成两篇文章了,我真的很怕读者看的时候失去动力,动不动就七八万字的博客,看着就害怕。虽然主要是代...

    晨曦_LLW
  • Android 天气APP(十六)热门城市 - 海外城市

    反正国内的天气也做好了,不妨做一下做一下国外的天气,国外的天气数据的展示,我将重新设计一套UI,区别于国内的天气UI,开搞~

    晨曦_LLW
  • AndroidStudio项目制作倒计时模块

    大家好,我是 Vic,今天给大家带来AndroidStudio项目制作倒计时模块的概述,希望你们喜欢

    达达前端

扫码关注云+社区

领取腾讯云代金券