android TCP 和 UDP总结(转)

之前写过一些关于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();拿到。

时间: 2024-10-03 04:16:53

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

Android中实现TCP和UDP传输实例

TCP和UDP在网络传输中非常重要,在Android开发中同样重要. 首先我们来看一下什么是TCP和UDP. 什么是TCP? TCP:Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的.可靠的.基于字节流的运输层(Transport layer)通信协议,由IETF的RFC 793说明(specified).在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能.应用层向TCP层发送用于网间传输的.用8位字节表示的数据流,然后TCP

Android编程:UDP客户端和TCP客户端

Android编程:UDP客户端和TCP客户端

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

TCP和UDP在网络传输中非常重要,在Android开发中同样重要. 首先来看一下什么是TCP和UDP. 什么是TCP? TCP:Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的.可靠的.基于字节流的运输层(Transport layer)通信协议,由IETF的RFC 793说明(specified).在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能.应用层向TCP层发送用于网间传输的.用8位字节表示的数据流,然后TCP把数

2015百度android开发岗位的一道简答题:TCP、UDP、HTTP之间的关系

题目:TCP.UDP之间的关系,TCP与HTTP之间的关系. 运输层主要为两台主机上的应用程序提供端到端的通信.在TCP/IP协议族中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议). TCP为两台主机提供高可靠的数据通信.它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等.由于运输层提供了高可靠的端到端的通信,因此应用层可以忽略所有这些细节.而另一方面,UDP则为应用层提供一种非常简单的服务.它只

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

网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层,一般编程人员接触最多的就是应用层和运输层,再往下的就是所谓的媒体层了,不是我们研究的对象. 下面是应用层.运输层,网络层.链路层通信协议概图.我们经常接触到的一般是: http协议:应用层协议,并且http协议是基于tcp连接的,主要解决的是如何包装协议的 tcp协议:运输层协议,通常也叫做tcp/ip协议,主要解决数据如何在网络中传输 udp协议:运输层协议,用户数据报协议,不可靠的协议,只负责把应用层的协议的数

Android TCP/IP 扫盲教程

TCP/IP 是因特网的通信协议. 通信协议是对计算机必须遵守的规则的描述,只有遵守这些规则,计算机之间才能进行通信. 浏览器和服务器都在使用 TCP/IP 因特网浏览器和因特网服务器均使用 TCP/IP 来连接因特网.浏览器使用 TCP/IP 来访问因特网服务器,服务器使用 TCP/IP 向浏览器传回 HTML. 电子邮件也使用 TCP/IP 电子邮件程序使用 TCP/IP 来连接因特网,这样才能收发邮件. 因特网地址也是 TCP/IP 你的因特网地址 211.161.247.1 也是标准的

TCP和UDP的区别

TCP和UDP的区别 TCP协议与UDP协议的区别 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的区别,我觉得这是没有从本质上弄清楚网络通信! TCP/IP协议是一个协议簇.里面包括很多协议的.UDP只是其中的一个.之所以命名为TCP/IP协议,因为TCP,IP协议是两个很重要的协议,就用他两命名了. TCP/IP协议集包括应用层,传输层,网络层,网络访问层. 其中应用层包括: 超文本传输协议(HTTP):万维网的基本协议

理解TCP和UDP协议

目录 TCP 协议 UDP协议 TCP和UDP的区别 TCP和UDP的使用场景 一 TCP协议 1.TCP的头部格式 理解TCP协议,首要的就是TCP协议的头部格式 ·        Source Port和Destination Port:分别占用16位,表示源端口号和目的端口号:用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接: ·        Sequence Number:用来标识从T

TCP和UDP基本原理

TCP和UDP基本原理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 传输层的主要任务就是建立应用程序间的端到端连接,并且为数据传输提供可靠或不可靠的通信服务,TCP/IP协议族的传输层协议主要包括TCP和UDP ,TCP是面向连接的可靠的传输层协议,它支持在不可靠网络上实现面向连接的可靠的数据传输 ,UDP是无连接的传输协议,主要用于在相对可靠的网络上的数据传输,或用于对延迟较敏感的应用等. 1.传输层的作用 a>.提供面向连接或无连接的服务 b>.维护连接状态 c>