Android Tcp操作
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操作相关推荐
- Android 文件操作
Android 文件操作操作时,要赋予相应的权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_S ...
- Android SDCard操作(文件读写,容量计算)
Android SDCard操作(文件读写,容量计算) android.os.Environment 提供访问环境变量 java.lang.Object android.os.Environment ...
- android的文件操作,Android文件操作概要1.ppt
Android文件操作概要1 Linux文件系统 在Linux中,文件的扩展名并不重要,一个文件是否可以访问或执行,是完全由文件属性来决定的.细心的读者会发现最后一列比较特殊,这一列描述的是Linux ...
- android tcp判断服务器是否断开,Android tcp客户端连接,然后从java服务器断开连接...
我在我的电脑上执行java服务器并让我的android设备连接到它.我可以连接它,但一旦连接就会断开连接.我确信在android方面我需要做一些事情,但我很少迷失它.我有互联网许可,所以很好.Andr ...
- android jxl.jar 使用,使用jxl.jar在Android中操作Excel表格——重中之重——对隐藏表的处理...
曾简单了解过C#,将Excel(数据库表)表中的数据导入到C#中,使用C#制作的图形化界面进行对Excel表中数据进行操作. 今天想试试,在Android中导入Excel表格进行操作.在网上查阅资料, ...
- Android数据库操作-1
Android采用关系型数据库SQLite3,它是一个支持SQL轻量级的嵌入式数据库,在嵌入式操作系统上有很广泛的应用,WM采用的也是SQLite3<?xml:namespace prefix ...
- Android 常用操作
0.android studios使用介绍 使用介绍 android studio 常用小技巧 网址 1.怎么样添加第三方库 方法一:第一步:将第三方库以module的形式导入 第二步:选中要导入第三 ...
- Android自定义操作栏示例教程
In this tutorial we will create an app that consists of Android Custom Action Bar with a custom layo ...
- Android键盘操作的函数:onKeyDown, onKeyUp, on, onKeyMultiple
android Activity类onKeyUp() ,onKeyDown 略读 Activity.onKeyDown(); 当某个键被按下时会触发,但不会被任何的该Activity内的任何view处 ...
最新文章
- 从Nginx绑定80端口学套接字编程
- ​全球首个视频实验期刊JOVE征稿:植物微生物组学方法专刊(牛犇、韦中、高峥、王蒙岑)...
- 怎样查看光驱硬盘托架的尺寸
- 聊聊技术写作的个人体会
- Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory 思维 + dp
- 天玑机器人颈椎_天玑骨科手术机器人亮相机器人大会 误差不到1毫米
- 实时屏幕监控 linux面板,分享|LXDE、Xfce 及 MATE 桌面环境下的又一系统监视器应用:Multiload-ng...
- Metal:对 iOS 中 GPU 编程的高度优化的框架
- 首发Android 13!谷歌Pixel 7 Pro渲染图曝光:后置相机模组吸睛
- MATLAB获取系统时间
- perl 安装 ZooKeeper模块
- linux 桌面时间,桌面锁屏时钟下载-桌面锁屏时钟appv2.8.1-Linux公社
- 【LOJ574】「LibreOJ NOI Round #2」黄金矿工
- 树莓派编译工作空间卡死
- 使用NVM安装NodeJS(原创 最全笔记)
- C# 取QQ会话记录
- 三十、非谓语动词_作状语
- 区块链应该打造国产操作系统
- 【Foobar 2000】如何为本地歌曲音乐评级、打分、评分、打小星星?喜爱程度分级-playcount、quick tagger
- 【CET4四级英语】【单词】单词的同义替换(1)