Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】


https://blog.csdn.net/liuhaomatou/article/details/41075701


一、简单的网络知识

1、网络模型:

①、OSI/RM(Open System Interconnection Reference Model开放式系统互连基本参考模型),是由ISO(International Standards Organization国际标准化组织)提出的网络参考模型。

②、TCP/IP(Transmission Control Protocol/Internet Protocol 传输控制协议/因特网互联协议)

③、两种网络模型的主要区别:

       OSI/RM7层模型。从低到高分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

                     OSI/RM模型的网络层同时支持面向连接和无连接的通信,但是传输层只支持面向连接的通信。

       TCP/IP4层模型。从低到高分别是:网络接口层、网际层、传输层、应用层

扫描二维码关注公众号,回复: 1948068 查看本文章

                     TCP/IP模型的网络层只提供无连接的服务,但是传输层上同时提供两种通信模式。

④、网络参考模型简图:


⑤、OSI/RM七层简述:

       物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。主要作用是在物理媒体上传输原始的数据比特流(bit

       数据链路层:主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装。将数据分成一个个数据帧(frame),以数据帧为单位传输。有应有答,遇错重发

       网络层:主要将从下层接收到的数据进行IP地址的封装与解封装。将数据分成一定长度的分组(数据包package),将分组穿过通信子网(即:下三层),从源端选择路径后传到目的端。

       传输层为会话层实体提供透明、可靠的数据传输服务,保证端到端的数据完整性;选择网络层的最适宜的服务;提供建立、维护和拆除传输连接功能。这一层传输的数据叫做段(segment)。

       会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。完成通信进程的逻辑名字(IP地址)与物理名字(MAC地址)间的对应;提供会话管理服务

       表示层主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等(也就是把计算机能够识别的东西转换成人能够能识别的东西(如图片、声音等)。

       应用层主要是一些终端的应用。提供应用程序访问OSI环境的方式。可以理解为人们在电脑屏幕上能够看到的东西。

 

2、网络通信三要素:

①、IP地址(Internet Protocol Address)用来标识网络上的一台独立的主机

       特点:

  •  32个二进制位,即4个字节组成。每两个字节间用一个点(.)来分隔;例如:192.168.100.10
  •  IP地址通常用十进制数进行表示;
  •  IP地址可以分为A、B、C、D、E五类。比较常用的是ABC三类。
  •  IP地址 = 网络地址 + 主机地址
              网络号:用于识别主机所在的网络/网段。
              主机号:用于识别该网络中的主机。
  • l  IP地址分为IPV4、IPV6两类。

 

                                                                              IP地址分类以及范围:

   序号   

     地址分类     

地址范围

1

A类

1.0.0.1~129.255.255.254

2

B类

     128.0.0.1~191.255.255.254     

3

C类

192.0.0.1~223.255.255.254

4

D类

224.0.0.1~239.255.255.254

5

E类

240.0.0.1~255.255.255.254

 

        缺点:

               IP地址都是由数字组成,不太方便记忆。(但是可以将IP地址和域名对应起来,利用DNS解析就可以通过域名得到IP地址,只需要记住比较好记的域名就可以了)

        特殊的IP地址:127.0.0.1(本地回环地址、保留地址)可用于简单的测试网卡是否故障。表示本机。


②、端口号:用于标识进程的逻辑地址。不同的进程都有不同的端口标识。

       端口:要将数据发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这些数字,则将这些数字称为端口。(此端口是一个逻辑端口)

       有效端口:范围是0~65535,其中0~1024是系统使用或者保留端口

 

③、传输协议:通讯的规则。例如:TCPUDP协议

      

1、网络通讯步骤:

       确定对端IP地址→ 确定应用程序端口 → 确定通讯协议

 

       总结:网络通讯的过程其实就是一个(源端)不断封装数据包和(目的端)不断拆数据包的过程。

 

       简单来说就是:发送方利用应用软件将上层应用程序产生的数据前后加上相应的层标识不断的往下层传输(封包过程),最终到达物理层通过看得见摸得着的物理层设备,例如:网线、光纤…等将数据包传输到数据接收方,然后接收方则通过完全相反的操作不断的读取和去除每一层的标识信息(拆包过程),最终将数据传递到最高层的指定的应用程序端口,并进行处理。



二、Java中网络通信三要素的体现

1、IP地址:在Java中,使用java.net包中的InetAddress类来描述IP地址。

2、InetAddress类的继承体系:

         InetAddress

                |--Inet4Address:用于表示IPV4

                |--Inet6Address:用于表示IPV6

             

       注意:InetAddress类没有构造方法,无法通过new去实例化对象。但是可以通过InetAddress类提供的静态方法来获取该类的对象,用该类接收。同时可以通过InetAddress类提供的相关方法来获取需要的信息,例如:IP地址、主机名等等。

 

InetAddress类的常用方法:

InetAddress getByName(String host):通过主机名获取InetAddress对象。

InetAddress getLocalHost():获取本机的InetAddress对象。

String getHostName():获取主机名。

String getHostAddress():获取主机的IP地址。

代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.net.*;  
  2. class IPDemo  
  3. {  
  4.        public static void main(String[] args) throws Exception  
  5.        {  
  6.               InetAddress i = InetAddress.getLocalHost();  
  7.    
  8.               System.out.println(i.toString());     //获取当前主机的主机名和IP地址  
  9.               System.out.println("ipaddress:"+i.getHostAddress());    //获取本机ip地址。  
  10.               System.out.println("hostname:"+i.getHostName());    //获取本机主机名。  
  11.    
  12.               InetAddress ia = InetAddress.getByName("www.baidu.com");  
  13.               System.out.println("ipaddress:"+ia.getHostAddress());   //获取百度主机的ip地址。  
  14.               System.out.println("hostname:"+ia.getHostName());   //获取百度主机的主机名。  
  15.        }  
  16. }  

输出结果:

hy-PC/172.16.128.143

ip address:172.16.128.143

hostname:hy-PC

ip address:119.75.218.77

hostname:www.baidu.com

 

由于可以通过InetAddress类的方法来获取指定域名主机的IP地址,但是由于有些域名有多个IP地址,例如:百度、新浪、搜狐等服务器主机名可能对应多个IP地址,所以可以通过InetAddress类中的getAllByName()方法来获取。

代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.net.*;  
  2. class IPDemo  
  3. {  
  4.        public static void main(String[] args) throws Exception  
  5.        {  
  6.               //可以通过InetAddress类中的静态方法getAllByName()来获取与指定主机名对应的多个IP地址信息。用一个InetAddress型数组接收。  
  7.               InetAddress[] iaa = InetAddress.getAllByName("www.qq.com");  
  8.               for(InetAddress ia : iaa)  
  9.               {  
  10.                      System.out.println(ia.toString());   //通过高级for循环进行打印输出。  
  11.               }  
  12.        }  
  13. }  

输出结果:

www.qq.com/101.226.129.158

www.qq.com/101.226.103.106

 

4、端口:由于端口都是用数字进行标识,所以没有必要将端口封装成对象。

 

5、传输协议TCP和UDP

①、UDPUser Datagram Protocol用户数据报协议

特点:

  •  面向无连接:传输数据之前源端和目的端不需要建立连接。
  •  每个数据报的大小都限制在64K(8个字节)以内。
  •  面向报文的不可靠协议。(即:发送出去的数据不一定会接收得到)
  •  传输速率快,效率高。

     现实生活实例:邮局寄件、实时在线聊天、视频会议等。

      

②、TCPTransmission Control Protocol传输控制协议

特点:

  •  面向连接:传输数据之前需要建立连接。
  •  在连接过程中进行大量数据传输。
  •  通过“三次握手”的方式完成连接,是安全可靠协议。
  •  传输速度慢,效率低。

     现实生活实例:打电话、下载文件等。

 

小知识点:TCP6种标志位:SYN(建立联机)、ACK(确认)、PSH(传送)、FIN(结束)、RST(重置)、URG(紧急)

Sequence number(顺序号码)Acknowledge number(确认号码)

三次握手的过程:

第一次握手建立连接时,客户端发送SYN包(SYN=x)到服务器,并进入SYN_SEND状态,等待服务器确认。

第二次握手服务器收到SYN包,必须确认客户端的SYN(ACK=x+1),同时自己也发送一个SYN包(SYN=y),即SYN+ACK包,此时服务器进入SYN_RECV状态。

第三次握手客户端接收到服务器的SYN+ACK包,向服务器发送确认包(ACK=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

三次握手完成之后,客户端和服务器之间开始传送数据。

 

三次握手过程图解:

 

三次握手在现实生活中理解场景:

 

6、Socket的基本介绍:

①    Socket编程:通常所说的网络编程其实就是Socket编程。

②、什么是socket?

Socket的字面意思是插槽、插座的意思。其实,Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口

Socket通常也称作“套接字”,用于描述IP地址和端口。应用程序两端通过“套接字”向网络发出请求或者应答网络请求。


③、Socket和ServerSocket类位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。

在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。

不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。


④、Socket中的常用方法:

java.net.Socket类继承与Object,有8个构造方法。其中三个使用最频繁的方法:

void accept():用于获取连接到服务端的客户端对象,并且返回一个客户端的Socket对象实例。该方法是一个阻塞式方法。

"阻塞"使程序运行暂时"停留",直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。

 

InputStream getInputStream()方法获得网络连接输入,同时返回一个IutputStream对象实例,。
OutputStream getOutputStream():该方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。

     注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。

 

⑤、C/S模型程序开发原理:
   服务器Server:使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。

   客户端Client:使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话。会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个大于1024的端口。

 


三、TCP、UDP传输实现过程(步骤)

1、UDP传输:DatagramSocket/DatagramPacket

UDP传输实现步骤:

     ①、建立UDP传输的发送端和接收端。

     ②、提供数据,并将数据封装到数据包中。

     ③、调用Socket服务的发送、接收功能,将数据包发出去或者接收回来。

     ④、关闭Socket服务。

 

/*

需求:通过UDP传输方式,将一段文字数据发送出去。

 

定义UDP发送端:

思路(实现步骤):

1、建立UDP的Socket服务。

2、提供数据,并将数据封装到数据包中。

3、通过Socket服务的发送功能,将数据包发出去。

4、关闭资源。

*/

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.net.*;  
  2. class UdpSend  
  3. {  
  4.        public static void main(String[] args) throws Exception  
  5.        {  
  6.               //1、创建udp服务,通过DatagramSocket对象。  
  7.               DatagramSocket ds = new DatagramSocket();  
  8.    
  9.               //2、确定数据,并封装成数据包。  
  10.               byte[] buf = "udp I am coming...".getBytes();  //将数据封装成字节数组。  
  11.               DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.88"),10000);  //将指定长度的数据发送到指定IP地址主机的指定端口。  
  12.    
  13.               //3、通过socket服务,将已有的数据包发送出去。通过send方法。  
  14.               ds.send(dp);  
  15.    
  16.               //4、关闭资源。  
  17.               ds.close();  
  18.        }  
  19. }  

 

UDP接收端:

/*

需求:定义一个应用程序,用于接收udp协议传输的数据并处理的。

思路(实现步骤):

1、定义UDPSocket服务。通常会监听一个端口,其实就是给这个接收网络应用程序定义数字标识。方便于明确哪些数据过来,该应用程序可以处理。(如果不指定监听端口,系统会自动分配一个监听端口)

2、定义一个数据包,因为要存储接收到的字节数据。因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。

3、通过Socket服务的receive方法将收到的数据存入已定义好的数据包中。

4、通过数据包对象的特有功能,将这些不同的数据取出。打印在控制台上。

5、关闭资源。

*/

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.io.*;  
  2. import java.net.*;  
  3. class UdpRece  
  4. {  
  5.     public static void main(String[] args) throws Exception  
  6.     {  
  7.         //1、创建UDP的Socket服务。建立端点。  
  8.         DatagramSocket ds = new DatagramSocket(10000);  
  9.   
  10.         //2、定义数据包。用于存储数据。  
  11.         byte[] buf = new byte[1024];  
  12.         DatagramPacket dp = new DatagramPacket(buf,buf.length);  
  13.   
  14.         //3、通过Socket服务的receive方法,将收到的数据存入数据包中。  
  15.         ds.receive(dp);  //receive方法是一个“阻塞式”方法,相当于线程当中的wait方法。即当没有数据发送过来的时候,就一致处于等待状态。  
  16.   
  17.         //4、通过数据包的方法获取其中的数据。  
  18.         String ip = dp.getAddress().getHostAddress();  //获取ip地址。  
  19.         String data = new String(dp.getData(),0,dp.getLength());  //获取数据。  
  20.         int port = dp.getPort();  //获取端口。  
  21.   
  22.         System.out.println(ip+"::"+data+"::"+port);  
  23.   
  24.         //5、关闭资源。  
  25.         ds.close();  
  26.     }  
  27. }  


2、TCP传输:Socket/ServerSocket

TCP传输实现步骤:

     ①、建立TCP传输的客户端(Socket)和服务端(ServerSocket)

     ②、建立连接后,通过Socket中的IO流进行数据的传输。

     ③、关闭Socket服务。

 

TCP传输基本思路:

①、客户端:

  1.  客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异常。
  2.  连接成功,说明客户端与服务端建立了通道,那么通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通过getInputStream(),getOutputStream()获取即可。
  3.  与服务端通讯结束后,关闭Socket服务。

 

②、服务端:

  1.  服务端需要明确它要处理的数据是从哪个端口进入的。(监听端口)
  2.  当有客户端访问时,要明确是哪个客户端,可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输。
  3.  当该客户端访问结束,关闭该客户端服务。

 

③ 、TCP传输示例图:


 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:10px;">import java.io.*;  
  2. import java.net.*;  
  3. /* 
  4. 客户端: 
  5. 通过查阅Socket对象,在该对象建立时就可以去连接指定主机。 
  6. 因为TCP是面向连接的,所以在建立Socket服务时,就要有服务端存在并连接成功。形成通路后,在该通道进行数据的传输。 
  7.   
  8. 需求:给服务端发送一个文本数据。 
  9.   
  10. 步骤: 
  11. 1、创建Socket服务,并指定要连接的主机和端口。 
  12. */  
  13. class TcpClient  
  14. {  
  15.        public static void main(String[] args) throws Exception  
  16.        {  
  17.               //创建客户端的Socket服务,指定目的主机和端口。  
  18.               Socket s = new Socket("192.168.1.88",10003);  
  19.    
  20.               //为了发送数据,应该获取Socket流中的输出流。  
  21.               OutputStream out = s.getOutputStream();  
  22.    
  23.               out.write("tcp I am coming...".getBytes());  
  24.    
  25.               s.close();  
  26.        }  
  27. }  


/*

需求:定义端点接收数据,并打印在控制台上。

 

服务端:

1、建立服务端的Socket服务,通过ServerSocekt();并监听一个端口。

2、获取连接过来的客户端对象。通过ServerSocketaccept方法完成。没有连接就会一直等,所以这个方法是一个阻塞式方法。

3、客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。并打印在控制台。

4、关闭服务端。(可选)

*/

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class TcpServer  
  2. {  
  3.        public static void main(String[] args) throws Exception  
  4.        {  
  5.               //建立服务端的Socket服务,并监听一个端口。  
  6.               ServerSocket ss = new ServerSocket(10003);  
  7.    
  8.               //通过accept方法获取连接过来的客户端对象。  
  9.               Socket s = ss.accept();  
  10.    
  11.               //获取客户端连接过来的主机IP地址。  
  12.               String ip = s.getInetAddress().getHostAddress();  
  13.               System.out.println(ip+"......connect");  
  14.    
  15.               //获取客户端发送过来的数据,那么要使用客户端对象的读取流方法来读取数据。  
  16.               InputStream in = s.getInputStream();  
  17.    
  18.               byte[] buf = new byte[1024];  
  19.               int len = in.read(buf);  
  20.    
  21.               System.out.println(new String(buf,0,len));  
  22.    
  23.               s.close();  //关闭客户端。  
  24.        }  
  25. }  

 

四、URLURLConnection

1、  URL(UniformResource Locator)统一资源定位符。

2、 URL类的常用方法:

       URL(String spec):根据 String表示形式创建 URL对象。

       URL(String protocol, String host, int port, Stringfile):根据指定 protocolhostport号和 file创建URL对象。

 

       String getFile():获取此 URL的文件名。

       String getHost():获取此 URL的主机名(如果适用)。

       String getPath():获取此 URL的路径部分。

       int getPort():获取此 URL的端口号。当返回值为-1的时候,表示使用http协议默认的端口号:80

       String getProtocol():获取此 URL的协议名称。

       String getQuery():获取此 URL的查询部分。(获取web路径之后的具体参数信息)

        URLConnection openConnection()返回一个URLConnection 对象,它表示到 URL 所引用的远程对象的连接。

      

代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.net.*;  
  2. class URLDemo  
  3. {  
  4.        public static void main(String[] args) throws Exception  
  5.        {  
  6.               URL url = new URL("http://172.16.128.143:8080/myweb/demo.html?name=haha&age=30");  
  7.    
  8.               System.out.println("getProtoclo():"+url.getProtocol());  
  9.               System.out.println("getHost():"+url.getHost());  
  10.               System.out.println("getPort():"+url.getPort());  
  11.               System.out.println("getPath():"+url.getPath());  
  12.               System.out.println("getFile():"+url.getFile());  
  13.               System.out.println("getQuery():"+url.getQuery());  
  14.    
  15.               /* 
  16.               intport = getPort(); 
  17.               if(port==-1) 
  18.                      port = 80; 
  19.               */  
  20.        }  
  21. }  

输出结果:

getProtoclo() :http

getHost() :172.16.128.143

getPort() :8080

getPath() :/myweb/demo.html

getFile() :/myweb/demo.html?name=haha&age=30

getQuery() :name=haha&age=30

 

3、  URLConnection(该类封装了访问远程网络资源的一般方法)

①、作用:可以通过URLConnecton类对象与远程服务器建立连接,并获取远程资源的一些属性信息。

URLConnection

      |-- HttpURLConnectionhttp请求和应答在应用层使用Http协议解析,请求和应答消息头不会显示出来。而Socket是在传输层。

      |-- JarURLConnection

代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.net.*;  
  2. import java.io.*;  
  3.    
  4. class URLConnectionDemo  
  5. {  
  6.        public static void main(String[] args) throws Exception  
  7.        {  
  8.               URL url = new URL("http://172.16.128.143:8080/myweb/demo.html");  
  9.         
  10.               URLConnection conn = url.openConnection();  
  11.               System.out.println(conn);    //HttpURLConnection  
  12.         
  13.               InputStream in = conn.getInputStream();  
  14.               byte[] buf = new byte[1024];  
  15.               int len = in.read(buf);  
  16.               System.out.println(newString(buf,0,len));  
  17.        }  
  18. }  

   

②、常用方法介绍:

int getContentLength()返回content-length 头字段的值。

String getContentType()返回content-type头字段的值。

InputStream getInputStream()返回从此打开的连接读取的输入流。

longgetDate():返回date 头字段的值。

代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.net.*;  
  2.    
  3. class URLConnectionDemo2  
  4. {  
  5.        public static void main(String[] args) throws Exception  
  6.        {  
  7.               URL urlPath = new URL("http://www.sina.com.cn");  
  8.               URLConnection conn = urlPath.openConnection(); //和远程对象建立连接。  
  9.               System.out.println("content-length:"+conn.getContentLength());  
  10.               System.out.println("content-type:"+conn.getContentType());  
  11.               System.out.println("data:"+conn.getDate());  
  12.        }  
  13. }  

输出结果:

content-length:538061

content-type:text/html

data:1403515169000

 


五、“域名解析”介绍

1DNSDomain Name System域名系统。是域名和IP地址的一种映射关系。

2DNS的作用:可以将域名解析成IP地址,方便记忆。(现实生活中一般以十进制的形式来表示IP地址,但是由于IP地址都是由数字组成,位数较多不易记忆,所以通过将域名和IP地址产生对应关系,而域名比较容易记忆,通过DNS服务来实现访问域名达到访问指定IP地址主机的效果)

3DNS的结构:

 

4、浏览器访问互联网主机的步骤(概述):

     ①.当使用浏览器访问一个网页的时候,本机首先查找本地hosts文件,如果本地hosts文件中有映射关系,则优先访问hosts文件中的域名对应的主机IP地址。

     ②.当本地hosts中没有相应的映射关系的时候,本机会向所在网络的DNS服务器请求要访问的网页。如果本地DNS服务器能找到要访问的网页主机,则将相应的信息反馈给请求端。如果没有找到,则本地DNS服务器继续向根域DNS服务器发出请求。

     ③、以访问网易邮箱mail.163.com为例:当本地DNS服务器向根DNS服务器请求时,根DNS服务器如果不知道网易主机的IP地址,但是却知道网易主机所在的域.com,接下来就告诉请求端去.com所在的顶级域中查找。

     ④、当向.com所在域的DNS服务器请求mail.163.com时,如果在.com域的DNS服务器中查不到的,但是可以告诉请求端去163.com这个二级域名所在域的DNS服务器中查找需要的信息。

     ⑤、而163.com这个域所在的DNS主机下面正好有mail.163.com这台主机,则此时便将要请求的主机IP地址告诉请求端,然后请求端直接通过该获取到的IP地址等信息去访问指定的邮箱资源。

 

访问步骤图例:


猜你喜欢

转载自blog.csdn.net/kongbaidepao/article/details/80824317