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

知识的领域是无限的,我们的学习也是无限期的。这篇文章主要讲述15.Android-实现TCP客户端,支持读写相关的知识,希望能为你提供帮助。
在上章14.android-使用sendMessage线程之间通信我们学习了如何在线程之间发送数据.
接下来我们便来学习如何通过socket读写TCP.
需要注意的是socket必须写在子线程中,不能在ui主线程中直接使用,所以我们这里创建了两个class:
MainActivity(主界面)、TcpThread(获取socket接收的数据)
由于代码有注释了,所以就不解释了.
1.gif效果如下

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

文章图片

 
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; //要发送的内容 Buttonbtn_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


// 1 UnknownHostException:如果无法识别主机的名字或IP地址,就会抛出这种异常。
// 2 ConnectException:如果没有服务器进程监听指定的端口,或者服务器进程拒绝连接,就会抛出这种异常。
// 3 SocketTimeoutException:如果等待连接超时,就会抛出这种异常。
// 4 BindException:如果无法把Socket对象与指定的本地IP地址或端口绑定,就会抛出这种异常
} 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; } }

  注意1:
使用inputStream.read(buffer)的时候如果读取不到数据,会进入阻塞状态,直到有数据来了,才会退出执行下个语句.如果想不使用阻塞的话,可以通过if(inputStream.available()> 0)来判断是否有数据来了.再读取即可
【15.Android-实现TCP客户端,支持读写】 

    推荐阅读