java 基础之网络编程 UDP/TCP
  HvTJUzsxOBtS 2023年11月25日 23 0


####1、网络通信协议简述
通过计算机可以使多台计算机进行连接,位于同一个网络中的计算机进行在进行连接和通信的时候需要遵守一定的规则。这就好比在一辆道路上运行的汽车需要遵守一定的交通规则。

在计算机网络中这些规则被称为网络通信协议,它对数据的传输格式、传输速度、传输步骤、等做了一系列的规定,通信双方必须同时遵守才能完成数据交换。网络通信由很多种,目前比较广泛使用的:TAP/IP(传输控制协议/因特网互联协议) ,它是一种包含TCP协议,IP协议,UDP协议,ICMP协议,和其他一些协议的协议组。,在学习各种协议之前我们先了解一下TCP/IP协议组的层次结构。

在进行数据传输的时候,需要发送的数据与收到的数据完全一样,这时就需要在原有的数据之上添加很多信息,以保证数据传输过过程中数据格式完全一直。TCP/IP协议的层次机构比较简单,共分为四层。

TCP/IP 协议中的四层分别是应用层,传输层、网络层,链路层,每层负责不同的通信功能,接下来具体看一下每层的功能:

1)应用层:主要负责应用程序的协议,如HTTP协议,FTP协议。
2)传输层:主要是网络通信进行通信,在进行网络通信的时,可以采用TCP协议,也可以采用UDP协议。
3)网络层:网络层是整个TCP/IP的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络
4)链路层:链路层主要用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如:针对光纤、双绞线提供的驱动。

####2、IP地址和端口号
1)IP
简单来讲IP号是为了让大家在网络中找到指定的计算机,端口号是为了找到这个计算机上指定的程序。

下面是细节知识:
要想使网络中的计算机能够进行通信,必须为每台计算机指定一个标志号,通过这个标识号来指定接受数据的计算机或者发送数据的计算机。在TCP/UDP协议中,这个标志号就是IP 地址,它可以唯一识别标示的每一台计算机。
现在广泛采用的IP 版本是IPv4,这是四个字节大小的二进制数来表示:如00001010000000000000000000000001。由于是二进制形式的很不好记,于是改变成每个字节用一个十进制标示:10.0.0.1 随着计算机的普及,IPv4的资源越来越少,于是出现了IPv6 16个字节标示的Ip地址。它的数据是2的128次方。这就解决IP资源分配问题。

2)端口号
通过IP地址可以找到指定的计算机,但是如果想访问目标计算机上的某一个应用程序,还需要指定端口。在计算机中不同的应用程序通过端口号区分的。
端口号是用两个字节(16位二进制表示),它的取值范围是065535。其中01023之间的端口是一些知名的网络服务和应用,普通的应用程序使用1024以上的端口,从而避免端口被另外一个应用或者服务所占用。

####3、java 程序定义InetAddress类来获取IP地址或者域名
JDK 里面提供一个InetAddress类,该类用于封装一个IP地址,并提供一系列与IP地址相关的方法:
1)InetAddress getByName(String host)
参数 host 表示指定的主机,该方法用于在给定主机名的情况下确定主机的IP地址
2)InetAddress getLocallHost()
创建一个表示本地主机的InetAddress对象
3)String getHostName()
得到IP地址的主机名。如果是本地计算机则返回本地计算机的名字。不是本地在计算机,则是主机名,如果没有域名,则返回IP地址。
4)boolean isReachable(int timeout)
判断指定的时间内是否能够到达指定地址
5)String getHostAddress()
得到字符串格式的原始地址

import java.net.InetAddress;
public class TestInetAddress {
public static void main(String[] args) throws Exception{
	InetAddress localAddress = InetAddress.getLocalHost();
	InetAddress remoteAddress = InetAddress.getByName("www.itcast.cn");
System.out.println("本机的IP地址:" + localAddress.getHostAddress());
System.out.println("itcast的IP地址:" + remoteAddress.getHostAddress());
System.out.println("3S内是否可以到达:" + remoteAddress.isReachable(3000));
System.out.println("itcast的主机名为:" + remoteAddress.getHostName());	
	}
}
运行的结果是:
本机的IP地址:192.168.1.185
itcast的ip地址:211.100.52.213
3S内是否可以到达:true
itcast的主机名是:www.itcast.cn(如果没有域名或者主机名,就返回字符IP地址)

####4、UDP/TCP协议
简单介绍:
udp:发送者不会在乎接受者有没有收到,接受者不会反馈发送者。
tcp:确立服务端,接受端,三次握手,信息反馈。

具体介绍:
UDP:用户数据报协议,即在数据传输的时候,数据的发送端和接收端不建立逻辑连接。

TCP:传输控制协议,面向连接的通信协议,即在发送数据之前在发送端和接收端建立逻辑连接,然后再发送数据。它提供了两台计算机之间可靠无差别的数据传输。

TCP传输要明确客户端和服务端。
TCP的三次握手:可以形象的理解为,礼貌的拜访朋友
(1)告诉朋友我打算去你那里,客户端向服务端发出连接请求,等待拂去端确认。
(2)朋友说可以呀,我有时间,服务端向客户端会送一个响应,通知客户端接收到了连接请求。
(3)和朋友约定具体时间,事宜,客户端再次向服务端发送确认信息,确定连接。

####5、UDP 通信
#####1)DatagramPacket类,通信的集装箱
UDP 通信类似于两个码头之间传递货物,传递货物需要集装箱呀,java JDK之中定义DatagramPacket类来当做传递数据的集装箱;
创造DatagramPacket类对象时,使用的构造方法是不同的,接收端的构造方法只需要接受一个字节数组来存放接收到的数据;发送端的构造方法不仅要有发送的数据,还要有要发送的计算机地址和端口号。
1)DatagramPacket(byte[] buf,int length);
我们看到只有两个参数,字节数组,字节大小,很明显是接收端的构造方法。
2)DatagramPacket(byte[] buf,int length,InetAddress addr, int port);
参数不仅包含封装数据的byte数组,数据长度,还有IP地址和端口号。可见这是发送端的构造方法。

3)DatagramPacket(byte[] buf,int offset ,int length);
相比较第一个方法多了一个参数 int offset,表示将接受到的数据从第几个开始,放到buf数组。
4)DatagramPacket(byte[] buf,int length,int offset, InetAddress addr, int port);
相比较第二个方法多了一个参数 int offset,表示发送数组buf里面数据的偏移量。

上面是DatagramPacket的构造方法,下面看一下这个类的几个常用方法。
(1)InetAddress getAddress()
这个方法用于返回发送端或者接收端的IP地址,如果是发送端DatagramPacket对象调用就返回接收端IP,反之。
(2)int getPort()
这个方法是用于返回发送端或者接收端的端口号,如果是发送端DatagramPacket对象调用,返回的是接收端的端口号,反之。
(3)byte[ ] getData()
这个方法用于返回将要发送或者接收的数据,如果是发送端DatagramPacket调用,返回发送的数据,同理。
(4)int getLength()
该方法用于返回将要发送或者接收数据的长度,如果是发送端DatagramPacket调用,返回发送的数据长度,同理。

#####2)、DatagramSocket 类,数据集装箱的码头
前面讲到的DatagramPacket就类似于集装箱,或者是货船,但是发送货物不单单有集装箱或者货船还不行的,要有码头。DatagramSocket就像是通信之间的码头一样。它的作用就是发送和接收DatagramPacket包裹。

同样在创建发送端或者接收端时使用的DatagramSocket对象,使用的构造方法也有所不同。
(1)DatagramSocket();
创建DatagramSocket的时候没有任何参数,没有指定端口号,此时计算机会分配一个没有被其他网络程序使用的端口号。
(2)DatagramSocket(int port);
此时传入一个端口参数,既可以当做发送端,也可以当做接收端的DatagramSocket对象,此时可以监听这个指定的端口。
(3)DatagramSocket(int port , InetAddress addr);
传入两个参数,不仅有端口号,还有IP地址,这种情况适用于计算机上有多个网卡的时候,我们知道一个网卡一个IP地址,此时我们可以指定计算机上哪个网卡来发送或者接受数据信息。

上面是DatagramSocket常见的构造方法,下面我们看一下它的常见方法,
(1)void receive(DatagramPackage p);
该方法用于将接收到的数据填充到DatagramPacket数据包里面,在接收到数据之前会一直处于阻塞状态,只有接受到数据这个方法才会运行。
(2)void send(DatagramPacket p);
该方法用于发送DatagramPackage数据包,发送的数据包包含发送的数据,数据长度,远程主机的IP地址,端口号。
(3)void close();关闭当前的Socket,通知驱动程序释放这个Socket保留资源。

UDP 实例

####6、TCP通信
TCP、UDP 都是可以实现通信,但是他们是有区别的。
1)UDP只有发送端,接收端,计算机之间可以相互发送数据;TCP区分客户端和服务端。
2)TCP 必须由客户端向服务端链接才能实现通信。服务端不能主动链接客户端。

在JDK中提供了两个类用于实现TCP程序,一个是 Serversocket类,用于表示服务
端,一个是 Socket类,用于表示客户端。通信时,首先创建代表服服务器端的
Serversocket对象,该对象相当于开启一个服务,并等待客户端的连接,然后创建代表客
户端的 Socket对象向服务器端发出连接请求,服务器响应请求,两者建立连接开始通 信。

#####1)ServerSocket 类,用于建立TCP服务端
JDK 包提供了一个ServerSocket 类,其构造方法:
1)ServerSocket();
创建的ServerSocket对象,没有绑定端口号,没有坚挺任何端口,不能直接使用。还需要调用bind(SocketAddress endpoint) 方法将其绑定到指定的端口才能使用。
2)ServerSocket(int port);
创建一个含有端口号的ServerSocket对象,就可以将其绑定到端口上,端口可以指定0,这样系统自动分配空闲端口,一般自己指定。
3)ServerSocket(int port, int backlog);
创建两个参数,backlog,代表当服务端比较繁忙的时候,可以保持链接请求的客户端的数量,默认50.
4)ServerSocket(int port, int backlog,InetAdderss bindAddr);
设定了相关IP,一般用于计算机含有多个网卡,指定使用哪个网卡,和客户端保持通信。

除了上述的构造方法,还有一些常用的方法:
(1)Socket accept();
该方法用于等待客户端的链接,在客户端链接之前一直处于阻塞状态,如果客户端链接就返回一个与之对应的Socket对象。
(2)InetAddress getInetAddress();
用于返回一个InetAddress对象,该对象封装了ServerSocket绑定的IP地址。
(3)boolean isClosed();
该方法用于判断ServerSocket对象是否为关闭状态,如果是返回true,反之false;
(4)void bind(SocketAddress endpoint);
该方法用于将ServerSocket 对象绑定到指定的IP和端口号。其中的endpoint 封装了ip和端口号。

ServerSocket 负责监听某台计算机的某个端口号,在创建ServerSocket对象之后,需要继续调用对象的accept()方法,接受来自客户端的请求。当执行了accept()方法后,服务器端程序会发生阻塞,直到客户端发生链接请求,accept()方法才会返回一个Socket对象用于和客户端实现通信,程序才能继续向下执行。

#####2)、Socket ,客户端通信
JDK 中提供了一个Socket类,用于实现客户端程序,它也有多种构造方法:
(1)Socket();
使用该构造方法创建Socket对象的时候,并没有指定端口号,也就意味着只创建了客户端对象,并没有去链接任何服务器。还需要通过调用connect(SocketAddress endpoint)方法才能够完成与指定的服务端的链接。参数endpoint用于封装IP地址和端口号。
(2)Socket(String host , int port);
该构造函数在创建时传递进来两个参数,会根据参数去链接指定的地址和端口号。host是一个字符型的IP地址。
(3)Socket(InetAddress address, int port);
该方法传递了两个参数,一个是链接指定的Address,另一个是端口号,参数address,是InetAddress类型的对象,用于封装一个IP地址。

Socket除了构造方法外,还有几个常用的方法:
(1)int getport();
该方法返回一个int类型的对象,该对象是Socket对象与服务器端链接的端口号。
(2)InetAddress getLocalAddress();
该方法用于获取Socket对象绑定的本地IP地址,并将IP地址封装成InetAddress类型的对象返回。
(3)void close();
该方法用于关闭Socket链接,结束本次通信。在关闭Socket之前,应将所有与Socket相关的所有输入输出流全部关闭,这是因为要释放资源。
(4)InputString getInputStream();
该方法返回一个InputStream类型的输入流对象,如果该对象是由服务器端的Socket返回,用于读取客户端发送的数据。反之用于读取服务端的数据。
(5)OutputStream getOutputStream();
该方法返回一个OutputStream类型的输出流对象,如果该对象由服务器段的Socket返回,就用于向客户端发送数据,反之,用于向服务端发送数据。

TCP 实例

参考文档:
Java基础入门 传智博客高教产品研发部

本人郑重声明,本博客所著文章、图片版权归权利人持有,本博只做学习交流分享所用,不做任何商业用途。访问者可將本博提供的內容或服务用于个人学习、研究或欣赏,不得用于商业使用。同時,访问者应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人的合法权利;如果用于商业用途,须征得相关权利人的书面授权。若以上文章、图片的原作者不愿意在此展示內容,请及时通知在下,將及时予以刪除。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月25日 0

暂无评论

推荐阅读
HvTJUzsxOBtS