网络通信-1(InetAddress、UDP、TCP、DatagramPacket、DatagramSocket、UDP通信示例)

1. 网络通信

1.1三要素:

  1. IP地址:网络中设备表示,可用主机名
  2. 端口号,用于表示进程的逻辑地址
  3. 传输协议:通讯的规则,常见的协议:TCP、IP

1.2 Socket

为网络编程提供的一种机制。

通信的两端都有Socket。

网络通信其实就是Socket间的通信,数据在两个Socket之间通过IO传输。

2. InetAddress

所有已实现的接口:

Serializable

直接已知子类:

Inet4Address(32位), Inet6Address(128位)

表示互联网协议 (IP) 地址。

  • IP 地址是 IP 使用的 32 位或 128 位无符号数字,它是一种低级协议,UDP 和 TCP 协议都是在它的基础上构建的。
  • InetAddress 的实例包含 IP 地址,还可能包含相应的主机名(取决于它是否用主机名构造或者是否已执行反向主机名解析)。
  • 地址类型:
    • 单播:单个接口的标识符。发送到单播地址的数据包被交付给由该地址标识的接口。
    • 多播:一组接口(通常属于不同的节点)的标识符。发送到多播地址的数据包被交付给由该地址标识的所有接口。
  • 主机名解析:
    • 主机名到 IP 地址的解析:通过使用本地机器配置信息和网络命名服务(如域名系统(Domain Name System,DNS)和网络信息服务(Network Information Service,NIS))来实现。要使用的特定命名服务默认情况下是本地机器配置的那个。对于任何主机名称,都返回其相应的 IP 地址。
    • 反向名称解析:意味着对于任何 IP 地址,都返回与 IP 地址关联的主机。

InetAddress 类提供将主机名解析为其 IP 地址(或反之)的方法。

2.1 方法

static InetAddress getByName(String host):在给定主机名的情况下确定主机的 IP 地址。

  • host:输出后是主机名/IP地址
  • IP:输出后是/IP地址
  • 有异常抛出:UnknownHostException

static InetAddress getLocalHost():返回本地主机

String getHostName():获取此 IP 地址的主机名。

String getHostAddress():返回 IP 地址字符串(以文本表现形式)。

2.2 使用

import java.net.InetAddress;
import java.net.UnknownHostException;public class Test{public static void main(String[] args) throws UnknownHostException{InetAddress local=InetAddress.getLocalHost();InetAddress remote=InetAddress.getByName("www.baidu.com");System.out.println("本地IP地址是:"+local.getHostAddress());System.out.println("百度的IP地址是:"+remote.getHostAddress());System.out.println("百度的主机名是:"+remote.getHostName());}
}

运行结果:

成功

3. UDP

User Datagram Protocol

用户数据包协议

是无连通协议:在发送数据时,数据的发送端和接收端不建立逻辑连接

消耗资源少,通信效率高

用于音频、视频和普通数据的传输

不保证数据完整性

数据包大小在64K

4. TCP

TAransmission Control Protocol

传输控制协议

面向连接的通信协议

在传输数据前,先在发送端和接受选建立逻辑连接,再传输数据。

提供了两台计算机之间的可靠的无差错疏忽传输

4.1 三次握手

创立连接

  1. C向S发出连接请求
  2. S向C回送一个响应
  3. C向S发送确认消息

可保证传输数据的安全性

eg.下载文件

5. DatagramPacket

此类表示数据报包。 UDP通信中发送或者接受的数据

数据报包用来实现无连接包投递服务(类似于集装箱)。

每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。

从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。

不对包投递做出保证。

5.1 构造方法

DatagramPacket(byte[] buf,int length): 构造DatagramPacket,用来接收长度为length的数据包。

  • 接收端的,只需要接收的一个字节数组来存放收到的数据,无需知道数据的来源

DatagramPacket(byte[] buf,int length,InetAddress address,int port): 构造数据报包,用来将长度为length的包发送到指定主机上的指定端口号。

  • 接收字节数组,指定发送目的端的IP地址和端口号。

5.2 方法

InetAddress getAddress():发挥某台机器的IP地址。此数据报将要发往该机器或者是从该机器接收到的。

int getPort():返回某远程主机的端口号。此数据报将要发往该主机或者是从该主机接收到的。

byte[] getData():返回数据缓冲区

int getLength():返回将要发送或接收到的数据的长度。

6. DatagramSocket

此类表示用来发送和接收数据报包的套接字。

数据报套接字是包投递服务的发送或接收点(类似于码头)。

每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。

在 DatagramSocket 上总是启用 UDP 广播发送。为了接收广播包,应该将 DatagramSocket 绑定到通配符地址。在某些实现中,将 DatagramSocket 绑定到一个更加具体的地址时广播包也可以被接收。

DatagramSocket s=new DatagramSocket(null);
s.bind(new InetSocketAddress(8888));

 这等价于:

DatagramSocket s=new DatagramSocket(8888);

两个例子都能创建能够在UDP 8888端口上接收广播的DatagramSocket。

6.1 构造方法

DatagramSocket():构造数据报套接字并将其绑定到本地主机上任何可用的端口。

DatagramSocket(int port):创建数据报套接字并将其绑定到本地主机上的指定端口。

  • 接收端:徐志鼎一个端口号,可监听指定的端口;
  • 发送端:可指定端口号;也可不指定,系统会分配一个没有被其他网络程序使用的端口号

6.2 方法

void receive(DatagramPacket p): 从此套接字接收数据报包。

void send(DatagramPacket p):从此套接字发送数据报包。

7. UDP网络程序

7.1 发送端

  • 创建DatagramSocket对象
  • 创建DatagramPacket对象,并封装数据
  • 发送数据
  • 释放流资源
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class Test{public static void main(String[] args) throws IOException{DatagramSocket sendSocket=new DatagramSocket();byte[] buffer="hello,UDP".getBytes();DatagramPacket dp=new DatagramPacket(buffer,buffer.length,InetAddress.getByName("***本机IP地址***"),8888);sendSocket.send(dp);sendSocket.close();}
}

7.2 接收端

  • 创建DatagramSocket对象
  • 创建DatagramPacjet对象
  • 接收数据存储到DatagramPacket对象中
  • 获取DatagramPacket对象的内容
  • 释放流资源
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class DemoTest{public static void main(String[] args) throws IOException {DatagramSocket receiveSocket=new DatagramSocket(8888);byte[] buffer=new byte[1024];DatagramPacket dp=new DatagramPacket(buffer,1024);receiveSocket.receive(dp);InetAddress ipAddress=dp.getAddress();String ip=ipAddress.getHostAddress();byte[] data=dp.getData();int length=dp.getLength();String datastr=new String(data,0,length);System.out.println("IP地址:"+ip+",数据是:"+datastr);receiveSocket.close();}
}

运行结果:

7.3 分析

发送端

DatagramPacket dp=new DatagramPacket(buffer,buffer.length,InetAddress.getByName("***本机IP地址***"),8888);如果此句中,主机名错,UnknowHostException;端口号错,可正常发出,接收端收不到。

无连接的协议,无接收端也可运行。

接收端

启动两次接收端:

  • 第一次正常
  • 第二次:BindException,端口号已绑定。
    • 端口号不可重复,它是一个进程在内存中的地址


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部