15.Android-實現TCP客戶端,支持讀寫

来源:https://www.cnblogs.com/lifexy/archive/2020/02/13/12304497.html

在上章14.Android-使用sendMessage線程之間通信我們學習瞭如何線上程之間發送數據. 接下來我們便來學習如何通過socket讀寫TCP. 需要註意的是socket必須寫在子線程中,不能在ui主線程中直接使用,所以我們這裡創建了兩個class: MainActivity(主界面)、Tc ...


在上章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;
        }
}

 


您的分享是我們最大的動力!

更多相關文章
  • 下載安裝Kibana 1. 下載地址:https://www.elastic.co/cn/downloads/kibana 2. 解壓下載的壓縮包 [[email protected] ~]# tar -zxvf kibana-7.6.0-linux-x86_64.tar.gz 3. 給es用戶分配許可權 ...
  • 前面文章分享了Linux下常用命令以及Shell編程相關知識,本節繼續學習Linux用戶管理及文件許可權控制。 ...
  • CRUD 在我們的項目中有日誌是一個必不可少的東西,但是日誌的檢索是一個很麻煩的事情,如每天一個日誌,要找到問題就得一個一個找,並不能做到檢索功能,這還算好的,如果是分散式的,每個機器都得找一遍,這種效率太低,當然可以把日誌收集到一個文件中,多個機器每天的日誌可以收集到一塊,如果把所有的日誌收集一塊 ...
  • sprd_battery.c 是充電驅動,這個是充電功能的核心內容,電量顯示策略、溫度檢測策略、充電保護機制等功能在這裡實現,功能實現與硬體細節剝離,調用通用介面實現邏輯控制; 1 sprdbat_probe函數: 1.1 解析設備樹: sprdbat_parse_dt函數如下: 2. 各個工作隊列 ...
  • 鳴謝:http://blog.csdn.net/leimengyuanlian/article/details/18748599 http://www.cnblogs.com/maowang1991/archive/2013/02/05/2893142.html https://www.cnblog ...
  • 編譯安裝redisd [toc] 安裝方法: yum安裝 1. 查看yum倉庫redis版本 2. yum安裝 3. 啟動服務並設為開機啟動 4. 查看redis埠 5. 測試登錄redis 6. 測試使用 編譯安裝 下載當前最新release版本redis源碼包 :http://download ...
  • Apache Flink社區宣佈Flink 1.10.0正式發佈! 本次Release版本修複1.2K個問題,對Flink作業的整體性能和穩定性做了重大改進,同時增加了對K8S,Python的支持。 這個版本標志著與Blink集成的完成,並且強化了流式SQL與Hive的集成,本文將詳細介紹新功能和主 ...
  • 1、使用 show status 瞭解各種 SQL 的執行頻率 該命令可以查詢 sql 命令的執行次數。 2、定位執行效率較低的 SQL 語句 定位執行效率較低的 SQL 一般有兩種方法: 1. 通過慢查詢日誌定位效率低的 SQL,用 該選項啟動; 2. 慢查詢日誌在查詢結束後才會記錄,所以在應用執 ...
一周排行
  • 微信公眾號dotnet跨平臺2020年初做的一個關於中國.NET開發者調查收到了開發者近 1400 條回覆。這份調查報告涵蓋了開發者工具鏈的所有部分,包括編程語言、應用架構、應用伺服器、運行時平臺、框架技術、框架配置、IDE、.NET/.NET Core 發行版部署模式、構建工具和Kubernete... ...
  • Winform控制項的雙緩衝。控制項的雙緩衝屬性是隱藏的,可以通過反射改變其屬性值。 lv.GetType().GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(lv, true, ...
  • 1. 需求 上圖這種包含多選(CheckBox)和單選(RadioButton)的菜單十分常見,可是在WPF中只提供了多選的MenuItem。順便一提,要使MenuItem可以多選,只需要將MenuItem的 屬性設置為True: 不知出於何種考慮,WPF沒有為MenuItem提供單選的功能。為了在 ...
  • gRPC的結構 在我們搭建gRPC通信系統之前,首先需要知道gRPC的結構組成。 首先,需要一個server(伺服器),它用來接收和處理請求,然後返迴響應。 既然有server,那麼肯定有client(客戶端),client的作用就是向server發送請求,具體就是生成一個請求,然後把它發送到ser ...
  • 區別 OpenId: Authentication :認證 Oauth: Aurhorize :授權 輸入賬號密碼,QQ確認輸入了正確的賬號密碼可以登錄 認證 下麵需要勾選的覆選框(獲取昵稱、頭像、性別) 授權 OpenID 當你需要訪問A網站的時候,A網站要求你輸入你的OpenId,即可跳轉到你的 ...
  • 前言 預計是通過三篇來將清楚asp.net core 3.x中的授權:1、基本概念介紹;2、asp.net core 3.x中授權的預設流程;3、擴展。 在完全沒有概念的情況下無論是看官方文檔還是源碼都暈乎乎的,希望本文能幫到你。不過我也是看源碼結合官方文檔看的,可能有些地方理解不對,所以只作為參考 ...
  • 簡介 基於生產者消費者模式,我們可以開發出線程安全的非同步消息隊列。 知識儲備 什麼是生產者消費者模式? 為了方便理解,我們暫時將它理解為垃圾的產生到結束的過程。 簡單來說,多住戶產生垃圾(生產者)將垃圾投遞到全小區唯一一個垃圾桶(單隊列),環衛將垃圾桶中的垃圾進行處理(消費者)。就是一個生產者消費者 ...
  • 很多時候,需要對類中的方法進行一些測試,來判斷是否能按要求輸出預期的結果。 C#提供了快速創建單元測試的方法,但單元測試不僅速度慢不方便,大量的單元測試還會拖慢項目的啟動速度。 所以決定自己搞個方便的測試用例。 控制台一句話調用。 測試用例.註冊並Print(EnumEx.Name); 結果畫面: ...
  • 常成員函數不能改變數據成員的值,例如定義坐標類Coordinate,成員函數changeX():void Coordinate::changeX(){ x = 10;}雖然changeX()沒有參數,但是它隱含一個參數——this指針:void Coordinate::changeX(Coordin... ...
  • 因為新冠肺炎疫情,診所還沒復工。這是在家用手機敲的,代碼顯示有問題。等復工以後在電腦上改,各位先湊和看吧。 支持向量機(Support Vector Machine, SVM)是一種基於統計學習的模式識別的分類方法,主要用於模式識別。所謂支持向量指的是在分割區域邊緣的訓練樣本點,機是指演算法。就是要找 ...
x