Tcp是基于传输层的面向连接的可靠通讯协议,其优点是基于连接,使得服务端和客户端可以实现双向通信,且实时性高,在需要服务端主动向客户端推送数据的应用场景中,使用TCP协议是一种很好的方式。

初学Android,将Android中Tcp的使用方式记录一下,希望对新学Android开发的新同学有帮助,这里主要介绍TcpClient的使用,因为很少会用Android来建立TcpServer端。

这里主要介绍Tcp客户端的几个应用:

1.与服务器建立连接

2.向服务端发送数据

3.接收服务端返回的数据

4.断线重连机制

在Android中使用socket有两个地方需要注意的:

1.在AndroidMainfest.xml中需要添加对网络的权限支持

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

2.Android中规定对socket的操作必须在线程中进行,如在主线程中进行操作会出现无法收发数据的情况。

(1)创建socket,与服务器建立连接

InetSocketAddress SerAddr = new InetSocketAddress(”192.168.1.100“,9988); //设置服务的IP地址和端口
try {        socket.connect(SerAddr,3000);   //尝试连接服务器    }catch (Exception e){

}
(2)发送数据

try {    
  /注意采用utf-8编码确保中文传输不会乱码
    BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter( socket.getOutputStream(),"utf-8")); 
     bufferedWriter.write(”Hello“);     bufferedWriter.flush();
    }catch (Exception e){

}

   
(3)接收数据

try {
    inputStream = new DataInputStream(socket.getInputStream());
    if(inputStream.available()>0)    {
      byte[] recData = new byte[inputStream.available()];      inputStream.read(recData);
      String iText=new String(recData,"utf-8");

      }

    }catch (Exception e){

}

(4)断线重连

当保持长时间的连接时,难免会因为网络或其他原因导致客户端与服务端断开连接,所以代码里面应该定时的去检查连接状态,当连接断开时,

应该重新尝试连接服务端。我们这里可以使用socket.sendUrgentData(0xFF);函数来检测,当服务端断开时,连续三次调用此函数会出现异常。

我们可以根据是否出现异常来断定与服务器的连接情况。

try {    socket.sendUrgentData(0xFF);}catch (Exception e){    socket.close();        //关闭套接字,重新创建新的并调用connect函数重新连接    socket = new Socket();}

以下贴出TcpHelper类的具体代码:

public class TcpHelper{    private Socket socket;               private BufferedWriter  bufferedWriter;    private DataInputStream inputStream;    private boolean NeedStop;    private InetSocketAddress SerAddr;    public  String ErrMsg;    private ReadThread readThread;           //读取数据线程    private OnReceiveEvent receiveEvent;     //此事件用于当接收到数据时向主线程通知接收到的数据    private long LastCheckTime;    public static interface OnReceiveEvent{        public  void ReceiveBytes(byte[] iData);        public  void ReceiveString(String iData);    }    public enum EDataType{EDT_BYTE,EDT_STRING};    private EDataType dataType;    public TcpHelper(String HostIp,int HostPort) {        try {            LastCheckTime=System.currentTimeMillis();            readThread =new ReadThread();            NeedStop=false;            SerAddr =  new InetSocketAddress(HostIp,HostPort);            NeedStop=false;            socket = new Socket();            readThread.start();        }catch (Exception e)        {            ErrMsg=e.getMessage();        }    }    public void SendString(String iText){       //发送字符串        dataType=EDataType.EDT_STRING;        toSend(iText);    }    public void SendBytes(byte[] iBuf){     //发送字节流指令        dataType=EDataType.EDT_BYTE;        String iText = new  String(iBuf);        toSend(iText);    }    //发送数据线程    private void toSend(final String iText){        new Thread(                new Runnable() {                    @Override                    public void run() {                        try {                            bufferedWriter.write(iText);                            bufferedWriter.flush();                        } catch (Exception e) {                        }                    }                }        ).start();    }    public boolean isConnected(){        return socket.isConnected();    }    //设置通知事件    public void setReceiveEvent(OnReceiveEvent iEvent){        receiveEvent=iEvent;    }    //读取线程    private class ReadThread extends Thread{        @Override        public void run() {            while (!NeedStop){                try {                    if (!socket.isConnected() || socket.isClosed()){                        socket.connect(SerAddr,3000);                        if(bufferedWriter==null)                            bufferedWriter =new BufferedWriter(new OutputStreamWriter( socket.getOutputStream(),"utf-8"));                        if(inputStream==null)                            inputStream = new DataInputStream(socket.getInputStream());                    }                    else {                        if(inputStream.available()>0){                            byte[] recData = new byte[inputStream.available()];                            inputStream.read(recData);                            if(receiveEvent!=null)                            {                                if(dataType==EDataType.EDT_BYTE) {                                    receiveEvent.ReceiveBytes(recData);                                }                                else {                                    String s=new String(recData,"utf-8");                                    receiveEvent.ReceiveString(s);                                }                            }                        }                        if (System.currentTimeMillis()-LastCheckTime>5000)                        {                            try {                                LastCheckTime=System.currentTimeMillis();                                socket.sendUrgentData(0xFF);                            }catch (Exception e){                                socket.close();                                socket = new Socket();                                bufferedWriter=null;                                inputStream =null;                            }                        }                    }

                }catch (Exception e){

                }            }        }    }}

测试Tcp连接的Activity代码:

import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.widget.EditText;import android.widget.TextView;

public class TcpFormActivity extends Activity {    private TcpHelper tcpHelper;    private String SerIp;    private int SerPort;    private EditText InputMsg;    private TextView RecMsg;    private String TcpRecData;    private MyHandler handler;    private TcpReceive tcpReceive;    @Override    protected void onCreate(Bundle saveInstanceState){        super.onCreate(saveInstanceState);        setContentView(R.layout.activity_tcpform);        RecMsg = (TextView)findViewById(R.id.TVTcpData);        InputMsg =  (EditText)findViewById(R.id.EdtTcpMsg);    }    public class TcpReceive implements TcpHelper.OnReceiveEvent{        public  synchronized void ReceiveBytes(byte[] iData){        }        public  synchronized  void ReceiveString(String iData){            TcpRecData=iData;            Message msg=new Message();            msg.what=1;            handler.sendMessage(msg);        }    }    class MyHandler extends Handler {        public MyHandler() {        }        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case 1:                    RecMsg.append(TcpRecData);  //接收到数据显示到TextView上                    break;            }            super.handleMessage(msg);        }    }    public void onConnectClick(View view){        if(tcpHelper==null)        {            SerIp = ((EditText)findViewById(R.id.EdtTcpSerIp)).getText().toString();            SerPort =Integer.parseInt(((TextView)findViewById(R.id.EdtTcpPort)).getText().toString());            tcpHelper = new TcpHelper(SerIp,SerPort);            tcpReceive = new TcpReceive();            tcpHelper.setReceiveEvent(tcpReceive);            handler = new MyHandler();        }    }    public void onSendMsgClick(View view){        try {            String iText=InputMsg.getText().toString();            tcpHelper.SendString(iText);        }catch (Exception e)        {

        }    }}
 

转载于:https://www.cnblogs.com/WushiShengFei/p/7397947.html

Android Tcp操作相关推荐

  1. Android 文件操作

    Android 文件操作操作时,要赋予相应的权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_S ...

  2. Android SDCard操作(文件读写,容量计算)

    Android SDCard操作(文件读写,容量计算) android.os.Environment 提供访问环境变量 java.lang.Object android.os.Environment ...

  3. android的文件操作,Android文件操作概要1.ppt

    Android文件操作概要1 Linux文件系统 在Linux中,文件的扩展名并不重要,一个文件是否可以访问或执行,是完全由文件属性来决定的.细心的读者会发现最后一列比较特殊,这一列描述的是Linux ...

  4. android tcp判断服务器是否断开,Android tcp客户端连接,然后从java服务器断开连接...

    我在我的电脑上执行java服务器并让我的android设备连接到它.我可以连接它,但一旦连接就会断开连接.我确信在android方面我需要做一些事情,但我很少迷失它.我有互联网许可,所以很好.Andr ...

  5. android jxl.jar 使用,使用jxl.jar在Android中操作Excel表格——重中之重——对隐藏表的处理...

    曾简单了解过C#,将Excel(数据库表)表中的数据导入到C#中,使用C#制作的图形化界面进行对Excel表中数据进行操作. 今天想试试,在Android中导入Excel表格进行操作.在网上查阅资料, ...

  6. Android数据库操作-1

    Android采用关系型数据库SQLite3,它是一个支持SQL轻量级的嵌入式数据库,在嵌入式操作系统上有很广泛的应用,WM采用的也是SQLite3<?xml:namespace prefix ...

  7. Android 常用操作

    0.android studios使用介绍 使用介绍 android studio 常用小技巧 网址 1.怎么样添加第三方库 方法一:第一步:将第三方库以module的形式导入 第二步:选中要导入第三 ...

  8. Android自定义操作栏示例教程

    In this tutorial we will create an app that consists of Android Custom Action Bar with a custom layo ...

  9. Android键盘操作的函数:onKeyDown, onKeyUp, on, onKeyMultiple

    android Activity类onKeyUp() ,onKeyDown 略读 Activity.onKeyDown(); 当某个键被按下时会触发,但不会被任何的该Activity内的任何view处 ...

最新文章

  1. 从Nginx绑定80端口学套接字编程
  2. ​全球首个视频实验期刊JOVE征稿:植物微生物组学方法专刊(牛犇、韦中、高峥、王蒙岑)...
  3. 怎样查看光驱硬盘托架的尺寸
  4. 聊聊技术写作的个人体会
  5. Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory 思维 + dp
  6. 天玑机器人颈椎_天玑骨科手术机器人亮相机器人大会 误差不到1毫米
  7. 实时屏幕监控 linux面板,分享|LXDE、Xfce 及 MATE 桌面环境下的又一系统监视器应用:Multiload-ng...
  8. Metal:对 iOS 中 GPU 编程的高度优化的框架
  9. 首发Android 13!谷歌Pixel 7 Pro渲染图曝光:后置相机模组吸睛
  10. MATLAB获取系统时间
  11. perl 安装 ZooKeeper模块
  12. linux 桌面时间,桌面锁屏时钟下载-桌面锁屏时钟appv2.8.1-Linux公社
  13. 【LOJ574】「LibreOJ NOI Round #2」黄金矿工
  14. 树莓派编译工作空间卡死
  15. 使用NVM安装NodeJS(原创 最全笔记)
  16. C# 取QQ会话记录
  17. 三十、非谓语动词_作状语
  18. 区块链应该打造国产操作系统
  19. 【Foobar 2000】如何为本地歌曲音乐评级、打分、评分、打小星星?喜爱程度分级-playcount、quick tagger
  20. 【CET4四级英语】【单词】单词的同义替换(1)

热门文章

  1. javaScript中的几种排序方式
  2. 子数组最大值设计02
  3. 选项卡 都是显示在页面底部
  4. AgileEAS.NET平台开发实例-药店系统-数据库还原
  5. 定义简单的反射工厂示例
  6. Discuz!NT 在线用户功能简介
  7. 解决JQuery AutoComplete在IE9下出错的问题
  8. kafka--storm--mongodb
  9. Linux快速查看某条命令的版本和存放的位置(ls -l `which mvn`)
  10. 微信JS-SDK之图像接口开发详解