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();拿到。
android TCP 和 UDP总结(转)的更多相关文章
- android ------- TCP与UDP
TCP TCP(Transmission Control Protocol,传输控制协议) 即传输控制协议,是一种传输层通信协议 特点:面向连接.面向字节流.全双工通信.可靠 面向连接:指的是要使用T ...
- Android开发:如何实现TCP和UDP传输
TCP和UDP在网络传输中非常重要,在Android开发中同样重要. 首先来看一下什么是TCP和UDP. 什么是TCP? TCP:Transmission Control Protocol 传输控制协 ...
- Android如何实现TCP和UDP传输
TCP和UDP在网络传输中非常重要,在Android开发中同样重要. 首先我们来看一下什么是TCP和UDP. 什么是TCP? TCP:Transmission Control Protocol 传输控 ...
- android 网络编程--socket tcp/ip udp http之间的关系
网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层,一般编程人员接触最多的就是应用层和运输层,再往下的就是所谓的媒体层了,不是我们研究的对象. 下面是应用层.运输层,网络 ...
- fiddler 手机 https 抓包 以及一些fiddler无法解决的https问题http2、tcp、udp、websocket证书写死在app中无法抓包
原文: https://blog.csdn.net/wangjun5159/article/details/52202059 fiddler手机抓包原理 fiddler手机抓包的原理与抓pc上的web ...
- TCP与UDP传输协议
目录结构: contents structure [-] 1 TCP协议和UDP协议的比较 1.1 TCP协议 TCP的全称是Transmission Control Protocol (传输控制协议 ...
- android tcp通讯
Andoird TCP通讯 前言 最近在写一个即时通讯的项目,有一些心得,写出来给大家分享指正一下. 简单描述一下这个项目: 实时查询车辆运行状态的项目,走TCP通迅. 接口采用GZIP压缩. 后台是 ...
- C++网络套接字编程TCP和UDP实例
原文地址:C++网络套接字编程TCP和UDP实例作者:xiaojiangjiang 1. 创建一个简单的SOCKET编程流程如下 面向有连接的套接字编程 服务器: 1) 创建套接字(so ...
- 【校验】TCP和UDP的校验和
一开始,私以为校验和只是简单的求和得到的结果,后来在TCP和UDP里面看到使用的校验和方式有点奇怪--二进制反码(循环进位)求和. 人类的认知过程必将从简单到复杂,看下这个二进制反码循环求和是啥子意思 ...
随机推荐
- 【微服务架构】SpringCloud之Eureka(服务注册和服务发现基础篇)(二)
上篇文章讲解了SpringCloud组件和概念介绍,接下来讲解一下SpringCloud组件相关组件使用.原理和每个组件的作用的,它主要提供的模块包括:服务发现(Eureka),断路器(Hystrix ...
- 基于JDBC的数据库连接池技术研究与应用
引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及,计算机 应用程序已从传统的桌面应用转到Web应用.基于B/S(Browser/Server)架构的3层开 ...
- Delphi xe5 控件TIdhttp的用法post,get解决中文乱码问题
网络接口如下图: 浏览器演示如下:http://xxx.xxx.xxx.xxx/web/login!doLogin?data={"password":"yy123&quo ...
- uwsgi启动提示:probably another instance of uWSGI is running on the same address (:8002). bind(): Address already in use [core/socket.c line 769]
提示8002端口被占用,可以这样终止掉后再启动 sudo fuser -k 8002/tcp
- RobotFramework与Jenkins集成发送邮件
转: A. 目标:实现RobotFramework的脚本定时自动执行,执行完后自动将结果发送到指定邮箱 B. 前提1. 配置好Robot Framework的环境,脚本可以正常运行 2. ...
- CentOS7系统更改网卡名为eth0
centOS7系统更改网卡名为eth0 1.编辑grub参数 [root@localhost ~]# vim /etc/sysconfig/grub 2.在GRUB_CMDLINE_LINUX行中添加 ...
- 在Python程序中调用Java代码的实现
<原创不易,转载请标明出处:https://www.cnblogs.com/bandaobudaoweng/p/10785766.html> 前言 开发Python程序,需求中需要用到Ja ...
- C++小总结
1.C与C++的简单区别 1.建立的文件类型不一样,C语言是.c,C++是.cpp 2.引入的头文件不一样 3.C++有命名空间 4.输入输出语句不一样 5.C语言不允许重载,C++可以重载 6.自定 ...
- nginx负载均衡配合keepalived服务案例实战
本实验用4台 centos6 虚拟机,2台做负载均衡,2台做web服务器,都先装上nginx lb01:192.168.0.235 --主负载均衡器 lb02:192.168.0.236 --备负 ...
- 使用git提交代码简单说明
一. 图形化git 1.首先下载msysgit,和 tortoisegit, 先装msysgit再装小乌龟 2.运行git按照github上说明生成秘钥对 ssh-keygen -t rsa ...