java网络编程(四)
2016-12-17 18:45
267 查看
TCP是为数据的可靠传输而设计的,如果数据在传输中丢失或损坏,TCP会保证再次发送数据。如果数据包乱序到达,TCP会将其置回正确的顺序。
这个可靠性的代价就是速度,建立和撤销TCP连接会花费较长的时间。
用户数据报协议UDP是在IP之上发送数据的另一种传输层协议,速度快,但不可靠。
可以通过UDP实现一个可靠的文件传输,只是由应用程序负责可靠性,UDP不关心这一点。
java中UDP的实现分为两个类:DatagramPacket和DatagramSocket
DatagramPacket将数据字节填充到UDP包中,称为数据报。
DatagramSocket可以收发UDP数据报,发送数据时,要将数据放入DatagramPacket中,然后使用DatagramSocket将其发送;
接收数据时,可以从DatagramSocket中接收一个DatagramPacket对象。
在UDP中,关于数据报的所有信息(包括发送的目标地址)都包含在Packet中。
UDP没有两台主机间唯一连接的概念,一个socket会收发所有指向指定端口的数据,而不需要知道对方是谁。
UDP客户端:
//UDP客户端指定端口0,就是随机选择一个可用端口
DatagramSocket socket = new DatagramSocket(0);
socket.setSoTimeout(10000);
InetAddress host = InetAddress.getByName("time.nist.gov");
//发送的数据报,指出要连接的远程主机和端口
DatagramPacket request = new DatagramPacket(new byte[1], 1, host, 13);
//接收的数据报要足够大
DatagramPacket response = new DatagramPacket(new byte[1024], 1024);
socket.send(request);
socket.receive(response);
String result = new String(response.getData(), 0, response.getLength(), "US-ASCII");
UDP服务端
//服务器端监听13端口
DatagramSocket socket = new DatagramSocket(13);
while(true) {
try {
DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
//会无限阻塞,直到一个UDP数据报到达端口13
socket.receive(request);
String daytime = new Date().toString();
byte[] data = daytime.getBytes("US-ASCII");
//发送回的数据包括请求的客户端的IP和客户端的端口
DatagramPacket response = new DatagramPacket(data, data.length, request.getAddress(), request.getPort());
socket.send(response);
}catch (IOException ex) {
}
}
socket.close();
许多Internet协议同时有TCP和UDP实现,当主机接收到一个IP包时,主机会检查IP首部来确定它是TCP数据包还是UDP数据报。
根据约定,若同一个服务同时有TCP、UDP实现,就使用相同的端口号。
DatagramChannel类
//基于通道的服务端的UDP
DatagramChannel channel = DatagramChannel.open();
DatagramSocket socket = channel.socket();
SocketAddress address = new InetSocketAddress(9);
socket.bind(address);
ByteBuffer buffer = ByteBuffer.allocate(65507);
while(true) {
//若通道是阻塞的,则这个方法一直等待;若通道是非阻塞的,则没有包可读的情况下,立即返回null
SocketAddress client = channel.receive(buffer);
buffer.flip();
while(buffer.hasRemaining()) {
System.out.println(buffer.get());
}
buffer.clear();
}
通道通过configureBlocking(false)可设置非阻塞状态
IP组播:
初始的路由器只向靠近接收主机的路由器发送一份消息副本,然后这个路由器建立多个副本,发送给位于目的地或更靠近目的地的不同接收方。
Internet组播建立在UDP基础上。
组播设计尽可能无缝地用于Internet,大多数工作都是由路由器完成,对于应用程序员应当是透明的。应用程序只是将数据包发送给一个组播地址,它在功能上于任何其他IP地址没有区别。路由器将确保包被分发到该组播组中所有主机。
组播地址是称为组播组的一组主机的共享地址。任何发送给该组播地址的数据都会中继给组中的所有成员。组播组中的成员是开放的,主机可以在任何时候进入或离开组。
组可以是永久的,也可以是临时的。要创建一个新的组播组,就是在225.0.0.0到238.255.255.255之间随机选择一个地址,为该地址创建一个InetAddress对象,开始向它发送数据。
注意数据报中的TTL值,TTL是允许数据报经过的最大路由器数目,当达到这个最大值时,就会将这个包丢弃。
从程序员的角度看,组播和UDP的主要区别就是,你必须考虑TTL,这是IP首部中一个1到255的一个字节的数.
TTL字段最初是为了防止路由循环而设计的,以保证所有包最终都会被丢弃。
是否支持组播:
需要你的主机和远程主机之间必须有一个由组播路由器构成的路径,或者有些网站可能连接着特殊的组播隧道软件,可以通过所有路由器都理解的单播UDP传播组播数据。
向组播地址发送数据与向单播地址发送UDP数据很相似,不需要加入组播组就可以向组播地址发送数据。
从组播组接收数据就必须加入组播组了。
//组播监听器
InetAddress group = InetAddress.getByName("239.255.255.250");
int port = 1900;
MulticastSocket ms = new MulticastSocket(port);
ms.joinGroup(group);
byte[] buffer = new byte[8192];
while(true) {
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ms.receive(dp);
String s = new String(dp.getData(), "8859_1");
}
leaveGroup(组)用来离开组播组
setTimeToLive(数字)在向组播组发送数据时,用来设置TTL
这个可靠性的代价就是速度,建立和撤销TCP连接会花费较长的时间。
用户数据报协议UDP是在IP之上发送数据的另一种传输层协议,速度快,但不可靠。
可以通过UDP实现一个可靠的文件传输,只是由应用程序负责可靠性,UDP不关心这一点。
java中UDP的实现分为两个类:DatagramPacket和DatagramSocket
DatagramPacket将数据字节填充到UDP包中,称为数据报。
DatagramSocket可以收发UDP数据报,发送数据时,要将数据放入DatagramPacket中,然后使用DatagramSocket将其发送;
接收数据时,可以从DatagramSocket中接收一个DatagramPacket对象。
在UDP中,关于数据报的所有信息(包括发送的目标地址)都包含在Packet中。
UDP没有两台主机间唯一连接的概念,一个socket会收发所有指向指定端口的数据,而不需要知道对方是谁。
UDP客户端:
//UDP客户端指定端口0,就是随机选择一个可用端口
DatagramSocket socket = new DatagramSocket(0);
socket.setSoTimeout(10000);
InetAddress host = InetAddress.getByName("time.nist.gov");
//发送的数据报,指出要连接的远程主机和端口
DatagramPacket request = new DatagramPacket(new byte[1], 1, host, 13);
//接收的数据报要足够大
DatagramPacket response = new DatagramPacket(new byte[1024], 1024);
socket.send(request);
socket.receive(response);
String result = new String(response.getData(), 0, response.getLength(), "US-ASCII");
UDP服务端
//服务器端监听13端口
DatagramSocket socket = new DatagramSocket(13);
while(true) {
try {
DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
//会无限阻塞,直到一个UDP数据报到达端口13
socket.receive(request);
String daytime = new Date().toString();
byte[] data = daytime.getBytes("US-ASCII");
//发送回的数据包括请求的客户端的IP和客户端的端口
DatagramPacket response = new DatagramPacket(data, data.length, request.getAddress(), request.getPort());
socket.send(response);
}catch (IOException ex) {
}
}
socket.close();
许多Internet协议同时有TCP和UDP实现,当主机接收到一个IP包时,主机会检查IP首部来确定它是TCP数据包还是UDP数据报。
根据约定,若同一个服务同时有TCP、UDP实现,就使用相同的端口号。
DatagramChannel类
//基于通道的服务端的UDP
DatagramChannel channel = DatagramChannel.open();
DatagramSocket socket = channel.socket();
SocketAddress address = new InetSocketAddress(9);
socket.bind(address);
ByteBuffer buffer = ByteBuffer.allocate(65507);
while(true) {
//若通道是阻塞的,则这个方法一直等待;若通道是非阻塞的,则没有包可读的情况下,立即返回null
SocketAddress client = channel.receive(buffer);
buffer.flip();
while(buffer.hasRemaining()) {
System.out.println(buffer.get());
}
buffer.clear();
}
通道通过configureBlocking(false)可设置非阻塞状态
IP组播:
初始的路由器只向靠近接收主机的路由器发送一份消息副本,然后这个路由器建立多个副本,发送给位于目的地或更靠近目的地的不同接收方。
Internet组播建立在UDP基础上。
组播设计尽可能无缝地用于Internet,大多数工作都是由路由器完成,对于应用程序员应当是透明的。应用程序只是将数据包发送给一个组播地址,它在功能上于任何其他IP地址没有区别。路由器将确保包被分发到该组播组中所有主机。
组播地址是称为组播组的一组主机的共享地址。任何发送给该组播地址的数据都会中继给组中的所有成员。组播组中的成员是开放的,主机可以在任何时候进入或离开组。
组可以是永久的,也可以是临时的。要创建一个新的组播组,就是在225.0.0.0到238.255.255.255之间随机选择一个地址,为该地址创建一个InetAddress对象,开始向它发送数据。
注意数据报中的TTL值,TTL是允许数据报经过的最大路由器数目,当达到这个最大值时,就会将这个包丢弃。
从程序员的角度看,组播和UDP的主要区别就是,你必须考虑TTL,这是IP首部中一个1到255的一个字节的数.
TTL字段最初是为了防止路由循环而设计的,以保证所有包最终都会被丢弃。
是否支持组播:
需要你的主机和远程主机之间必须有一个由组播路由器构成的路径,或者有些网站可能连接着特殊的组播隧道软件,可以通过所有路由器都理解的单播UDP传播组播数据。
向组播地址发送数据与向单播地址发送UDP数据很相似,不需要加入组播组就可以向组播地址发送数据。
从组播组接收数据就必须加入组播组了。
//组播监听器
InetAddress group = InetAddress.getByName("239.255.255.250");
int port = 1900;
MulticastSocket ms = new MulticastSocket(port);
ms.joinGroup(group);
byte[] buffer = new byte[8192];
while(true) {
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ms.receive(dp);
String s = new String(dp.getData(), "8859_1");
}
leaveGroup(组)用来离开组播组
setTimeToLive(数字)在向组播组发送数据时,用来设置TTL
相关文章推荐
- Servlet,GenericServlet,HttpServlet源码解析
- 虚拟机的三种网络连接方式
- 网络IO-阻塞、非阻塞、同步、异步
- 如何测试网络连通性
- 推荐一款开源的C#TCP通讯框架
- Java 网络编程
- 基于TCP的服务器端/客户端(二)---------网络编程(Linux----C)
- 使用C++ REST SDK开发简单的Web(HTTP)服务
- 从零开始做远控 簡介篇 做一个属于你自己的远控
- l 4000 inux环境下配置tomcat HTTPS协议
- Android使用OkHttp,断网再联网,发不出请求
- [Cocos2d-x]网络协议之Scoket
- 前端学HTTP之安全HTTP
- Android网络状态之ConnectivityManager
- python 下载网络图片到本地
- 服务器如何处理http请求
- Android 网络请求及网络状态判断
- gitlab同步代码时https证书错误
- tigase 启用Http Rest API 问题整理
- 几款网络仿真软件