之前写过一些关于TCP和UDP数据传输的代码,比如使用TCP传输音视频数据包,P2P打洞中使用UDP等。写好之后就直接丢下了,没有总结下都。最近准备找工作,再拿来温习下。

1、还是先说点啥

暂时把自己的定位很明确,就是android应用层的开发,所以关于TCP/UDP的实现细节,暂时也不想去深究。但是心里清楚这个必须去看的,有时间推荐大家看看《TCP/IP详解》,或者网上有很多大牛的总结。

2、TCP

不知道为什么,这个总结不想写的太细,不贴代码写的细又不知道能总结啥,好纠结,可能就是认识有限吧,公司要是有个架构就好了。不说了,还是安安稳稳的写总结吧。TCP这个可能是我们用的比较多的或者说我用的比较多的,主要的工作还是进行大量数据的传输和心跳保持(想想去年面试的时候都不知道啥是心跳,汗……)。对于心跳保持,就是一个简单的小心跳包;大量数据的传输,这个也总结不了啥东西,代码就那样,就是一些细节说一下。

客户端:这个是我们关注的最多的,也是作为一个手机APP主要关注的,因为我们就是client

a、创建一个client socket

new Socket(ip, prot);

我们可以通过上面的方式创建一个socket,如果失败,会抛出IOException。参数中的IP和Port是目标服务器的IP和端口号。若你想得到本地的IP和端口可通过这个socket拿到。当然,创建socket还有多种构造方法,比如 new Socket(proxy) ,如果有需要你可以查阅相关说明。

b、发送和接收数据

拿到socket对象之后我们接着要做的事情就是从这个socket中拿到输入和输出流,这样我们才可以进行数据的发送和接收:

InputStream is = mSocket.getInputStream();
OutputStream out = mSocket.getOutputStream();

通过输出流,我们可以使用is.read(receiveBuffer)和out.write(data);来进行数据的收发。这里给两个简单实例:

接收数据:

	@Override
public void execute() {
try {
int count = is.read(receiveBuffer);
if (count == -1) {
notifyError();
}
byte[] data = getPacket(receiveBuffer, count, is);
mReceiverQueue.put(data);
} catch (InterruptedException e) {
e.printStackTrace();
notifyError();
} catch (IOException e) {
e.printStackTrace();
notifyError();
}
}

假如我们的数据包协议格式如下:

这个时候,如果进行大量数据传输的时候我们从InputStream中一次读取的数据可能不是一个完整的数据包。这个时候我们需要做下面的判断: a、读取的数据长度是否达到包头大小,若没有包头长,继续读,直到达到或者超过包头大小; b、从包头中解出长度字段,循环读取,直到读到长度字段标示长度为止; c、校验数据,去除包头,取出包体; d、重复上述步骤。

发送数据:

	@Override
public void execute() {
try {
byte[] data = mSenderQueue.take();
out.write(data);
} catch (InterruptedException e) {
e.printStackTrace();
notifyError();
} catch (IOException e) {
e.printStackTrace();
notifyError();
}
}

mSenderQueue和mReceiverQueue一样,都是阻塞队列。发送的时候,我们从队列中取出要发送的数据,然后通过输出流写入即可。这个地方比发送简单了一些。可能你已经注意到,我的发送和接收都用了阻塞队列,这个原因就是考虑到大量数据的时候做一个缓冲,如果没有缓冲,可能导致代码的阻塞。另外就是当我们的阻塞队列充满的时候可以手动丢弃一些数据,这个就是具体应用了。

服务端:这个可以简单了解下,可以java实现,也可C++等实现

首先,我们创建一个ServerSocket对象并指定一个端口号,通过这个对象的accept()方法等待客户的连接,这个方法是阻塞的;当有客户端连接上来之后,我们就拿到了连接的Socket,拿到这个socket之后的操作就和客户端一样了,最后看一下关键代码:

	try {
ServerSocket serverSocket = new ServerSocket(9559);
while (true) {
Socket socket = serverSocket.accept();
// new ServiceSocketThread(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}

因为服务端不可能只与一个客户端连接,因此上面的代码写在一个死循环中。拿到socket之后起一个新的线程来处理这个socket。

最后,还有一点需要注意的是:从Socket中拿到InputStream和OutputStream之后如果关闭它们,socket也将随之关闭(未验证)。

3、UDP

这个东西用的很少,就是当初测试P2P的时候用过。能想到的问题就是数据大小的问题,比如发送数据我们的数据定义为多大合适。但是最后没有实际的项目验证,在此也不好回答。先贴一段代码出来:

public class UDPServer extends BaseThread {

	/** 发送队列大小 */
public static final int SENDQUEUESIZE = 10;
/** 接收队列大小 */
public static final int RECEIVEQUEUESIZE = 10;
/** TCP接收缓存大小 */
public static final int RECEIVERBUFFERSIZE = 1024;
/** UDP接收缓存大小 */
public static final int RECEIVERPACKETSIZE = 1024 * 64; private int count = 0;
private DatagramPacket receivePacket;
private DatagramSocket mSocket; @Override
public boolean prepare() {
receivePacket = new DatagramPacket(new byte[RECEIVERPACKETSIZE], RECEIVERPACKETSIZE);
try {
mSocket = new DatagramSocket(9559);
} catch (SocketException e) {
System.out.println(String.format("udp connect init error: %s", e.getMessage()));
return false;
}
return true;
} @Override
public void execute() {
try {
mSocket.receive(receivePacket); byte[] data = receivePacket.getData();
int length = receivePacket.getLength();
int offset = receivePacket.getOffset();
System.out.print(++count
+ String.format("length:%d|%d, offset:%d, data: %s \n", length, data.length, offset, new String(data, "gbk")));
System.out.println(data[1024]);
} catch (SocketException e) {
System.out.println(String.format("udp connect init error: %s", e.getMessage()));
} catch (IOException e) {
System.out.println(String.format("udp connect init error: %s", e.getMessage()));
}
}
}

byte[] data = receivePacket.getData();这个地方拿到的data是缓冲区的大小,他们地址是样的,这个大家可以试试就知道。至于这个data中有多少数据,就需要我们通过receivePacket.getLength();拿到。

android TCP 和 UDP总结(转)的更多相关文章

  1. android ------- TCP与UDP

    TCP TCP(Transmission Control Protocol,传输控制协议) 即传输控制协议,是一种传输层通信协议 特点:面向连接.面向字节流.全双工通信.可靠 面向连接:指的是要使用T ...

  2. Android开发:如何实现TCP和UDP传输

    TCP和UDP在网络传输中非常重要,在Android开发中同样重要. 首先来看一下什么是TCP和UDP. 什么是TCP? TCP:Transmission Control Protocol 传输控制协 ...

  3. Android如何实现TCP和UDP传输

    TCP和UDP在网络传输中非常重要,在Android开发中同样重要. 首先我们来看一下什么是TCP和UDP. 什么是TCP? TCP:Transmission Control Protocol 传输控 ...

  4. android 网络编程--socket tcp/ip udp http之间的关系

    网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层,一般编程人员接触最多的就是应用层和运输层,再往下的就是所谓的媒体层了,不是我们研究的对象. 下面是应用层.运输层,网络 ...

  5. fiddler 手机 https 抓包 以及一些fiddler无法解决的https问题http2、tcp、udp、websocket证书写死在app中无法抓包

    原文: https://blog.csdn.net/wangjun5159/article/details/52202059 fiddler手机抓包原理 fiddler手机抓包的原理与抓pc上的web ...

  6. TCP与UDP传输协议

    目录结构: contents structure [-] 1 TCP协议和UDP协议的比较 1.1 TCP协议 TCP的全称是Transmission Control Protocol (传输控制协议 ...

  7. android tcp通讯

    Andoird TCP通讯 前言 最近在写一个即时通讯的项目,有一些心得,写出来给大家分享指正一下. 简单描述一下这个项目: 实时查询车辆运行状态的项目,走TCP通迅. 接口采用GZIP压缩. 后台是 ...

  8. C++网络套接字编程TCP和UDP实例

    原文地址:C++网络套接字编程TCP和UDP实例作者:xiaojiangjiang 1.       创建一个简单的SOCKET编程流程如下 面向有连接的套接字编程 服务器: 1)  创建套接字(so ...

  9. 【校验】TCP和UDP的校验和

    一开始,私以为校验和只是简单的求和得到的结果,后来在TCP和UDP里面看到使用的校验和方式有点奇怪--二进制反码(循环进位)求和. 人类的认知过程必将从简单到复杂,看下这个二进制反码循环求和是啥子意思 ...

随机推荐

  1. 洛谷P2387 [NOI2014]魔法森林(lct维护最小生成树)

    题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...

  2. 洛谷P4172 [WC2006]水管局长(lct求动态最小生成树)

    SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径, ...

  3. Linq实战 之 DataSet操作详解

    Linq实战 之 DataSet操作详解  一:linq to Ado.Net 1. linq为什么要扩展ado.net,原因在于给既有代码增加福利.FCL中在ado.net上扩展了一些方法. 简单一 ...

  4. Linux常用开发指令

    gcc mysqltest.c -o mysqltest `mysql_config –cflags –libs`

  5. 一个简单的C#+arcgis的非数据库版例子

    1.首先新建一个winform的项目. 2.确保C#工具箱包含ESRI的相关控件,如果没有就需要安装SDK. 如果VS中依旧不存在esri控件解决方案如下,以VS2013为例: (1)打开注册表,定位 ...

  6. HttpWebRequest(System.Net)模拟HTTP发送POST

    相关参考网上很多,但需要理解并转成自己的情况 public static string HttpWebRequestPost(string url, string param) { HttpWebRe ...

  7. Mysql链接字符串问题

    <add key="ConnstringMySql" value="server=xxx.xxx.xxx.xxx;database=YourDatabase;uid ...

  8. python,使用百度api实现复制截图中的文字

    百度云文字识别技术文档: 跳转 第三方模块安装: pip install baidu-aip pip install Pillow pip install keyboard pip install p ...

  9. BOI2007 Mokia | cdq分治求二维点数模板

    题目链接:戳我 也没什么,其实主要就是为了存一个求二维坐标上矩形内点的个数的模板.为了之后咕咕咕地复习使用 不过需要注意的一点是,树状数组传x的时候可千万不要传0了!要不然会一直死循环的...qwqw ...

  10. Django-01Django简介

    1 MVC与MTV模型 MVCWeb服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起,模型负责业 ...