网络编程学习笔记(未完结)

  IP地址,端口,URL:

IP地址:用来标识网络中的一个通信实体的地址。通信实体可以是计算机、路由器等。 比如互联网的每个服务器都要有自己的IP地址,而每个局域网的计算机要通信也要配置IP地址。路由器是连接两个或多个网络的网络设备。目前主流使用的IP地址是IPV4,但是随着网络规模的不断扩大,IPV4面临着枯竭的危险,所以推出了IPV6。

用InetAddress类可以创建本机或者利用域名/IP地址来创建对象,并通过getHostAddress(),getHostName()获取对象信息。

 1 InetAddress addr1 = InetAddress.getLocalHost();//为本机创建对象
 2     System.out.println(addr1.getHostAddress());//获取本机IP地址
 3     System.out.println(addr1.getHostName()); //获取本机名字
 4     System.out.println("----------------------------------");
 5     
 6     InetAddress addr2 = InetAddress.getByName("www.163.com");//为163创建对象,从名字来获取信息
 7     System.out.println(addr2.getHostAddress());//获取163IP地址
 8     System.out.println(addr2.getHostName()); //获取163域名
 9     System.out.println("----------------------------------");
10     
11     InetAddress addr3 = InetAddress.getByName("112.13.210.199");//为163创建对象,从名字来获取信息
12     System.out.println(addr3.getHostAddress());//获取163IP地址
13     System.out.println(addr3.getHostName()); //输出的也是IP地址
View Code

端口:IP地址用来标识一台计算机,但是一台计算机上可能提供多种网络应用程序,端口被用来区分这些不同的程序。端口是虚拟的概念,并不是说在主机上真的有若干个端口。通过端口,可以在一个主机上运行多个网络应用程序。 端口的表示是一个16位的二进制整数,对应十进制的0-65535。

用InetSocketAddress类可以利用域名/IP地址+端口号来创建对象,并通过getHostAddress(),getHostName()获取对象信息。

1         InetSocketAddress isa1 = new InetSocketAddress("127.0.0.1",8080);
2     System.out.println(isa1.getHostName());
3     System.out.println(isa1.getAddress());
4     
5     InetSocketAddress isa2 = new InetSocketAddress("localhost",9000);
6     System.out.println(isa2.getHostName());
7     System.out.println(isa2.getAddress());
View Code

URL:在www上,每一信息资源都有统一且唯一的地址,该地址就叫URL(Uniform Resource Locator),它是www的统一资源定位符。URL由4部分组成:协议 、存放资源的主机域名、资源文件名和端口号。如果未指定该端口号,则使用协议默认的端口。例如http 协议的默认端口为 80。 在浏览器中访问网页时,地址栏显示的地址就是URL。

可用URL类以URL来创建对象,并获取各种信息。以http://www.baidu.com:80/index.html?uname=shsxt&age=18#a为例:

协议:http
域名/IP:www.baidu.com
端口:80
请求资源:/index.html
参数:uname=shsxt&age=18
锚点:a

1 URL url = new URL("http://www.baidu.com:80/index.html?uname=shsxt&age=18#a");
2         System.out.println("协议-"+url.getProtocol());
3         System.out.println("域名/IP-"+url.getHost());
4         System.out.println("端口-"+url.getPort());
5         System.out.println("请求资源1-"+url.getFile());
6         System.out.println("请求资源2-"+url.getPath());
7         System.out.println("参数-"+url.getQuery());
8         System.out.println("锚点-"+url.getRef());
View Code

  网络通信协议:

      OSI七层协议模型

图12-1 七层协议模型.png

      TCP/IP网络通信协议是OSI模型的具体实现。

图12-2 开放系统互连参考模型与TCPIP参考模型对比.png

  TCP协议:

在网络通讯中,TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。TCP是面向连接的,传输数据安全,稳定,效率相对较低。

 TCP(Transfer Control Protocol)是面向连接的,所谓面向连接,就是当计算机双方通信时必需经过先建立连接,然后传送数据,最后拆除连接三个过程。

TCP在建立连接时又分三步走(三次握手Three-way Handshake):

      第一步:是请求端(客户端)发送一个包含SYN即同步(Synchronize)标志的TCP报文,SYN同步报文会指明客户端使用的端口以及TCP连接的初始序号。

      第二步:服务器在收到客户端的SYN报文后,将返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加一,ACK即确认(Acknowledgement)。

      第三步:客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加一,到此一个TCP连接完成。然后才开始通信的第二步:数据处理。

  UDP协议:

称为数据报通信方式。在这种方式中,每个数据发送单元被统一封装成数据报包的方式,发送方将数据报包发送到网络中,数据报包在网络中去寻找它的目的地。

UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。

大量的非核心数据可以通过UDP方式进行传递。 UDP是面向无连接的,传输数据不安全,效率较高。

  Socket套接字:

我们开发的网络应用程序位于应用层,TCP和UDP属于传输层协议,在应用层和传输层之间,使用套接Socket来进行分离

套接字就像是传输层为应用层开的一个小口,应用程序通过这个小口向远程发送数据,或者接收远程发来的数据;而这个小口以内,也就是数据进入这个口之后,或者数据从这个口出来之前,是不知道也不需要知道的,也不会关心它如何传输,这属于网络其它层次工作。

Socket实际是传输层供给应用层的编程接口。Socket就是应用层与传输层之间的桥梁。使用Socket编程可以开发客户机和服务器应用程序,可以在本地网络上进行通信,也可通过Internet在全球范围内通信。

TCP套接字通信双方须链接,且有主次之分。UDP套接字无须链接,通信双方平等

图12-5 Socket的作用.png

  数据封装与解封:

1.数据发送处理过程

        (1)应用层将数据交给传输层,传输层添加上TCP的控制信息(称为TCP头部),这个数据单元称为段(Segment),加入控制信息的过程称为封装。然后,将段交给网络层。

        (2)网络层接收到段,再添加上IP头部,这个数据单元称为包(Packet)。然后,将包交给数据链路层。

        (3) 数据链路层接收到包,再添加上MAC头部和尾部,这个数据单元称为帧(Frame)。然后,将帧交给物理层。

        (4)物理层将接收到的数据转化为比特流,然后在网线中传送。

2.数据接收处理过程

        (1)物理层接收到比特流,经过处理后将数据交给数据链路层。

        (2)数据链路层将接收到的数据转化为数据帧,再除去MAC头部和尾部,这个除去控制信息的过程称为解封,然后将包交给网络层。

        (3)网络层接收到包,再除去IP头部,然后将段交给传输层。

        (4)传输层接收到段,再除去TCP头部,然后将数据交给应用层。

  网络爬虫:

从网络上获取数据的过程。

1.给一个URL

2.下载资源

3.分析资源(使用正则表达式)

4.操作数据

1,2步程序如下:

利用url创建对象后,用InputStreamReader与readLine()方法下载资源。

1 URL url = new URL("http://www.baidu.com");//给一个url
2       InputStream is = url.openStream();//下载资源
3       BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
4       String msg = null;
5       while(null!=(msg=br.readLine())) {
6           System.out.println(msg);
7       }
8       br.close();
9     }
View Code

有些网站不可直接下载资源,可以用模拟浏览器的方法获取资源:

获取网页UserAgent方法:打开网页,Fn+F12,Network,Headers

 1 URL url = new URL("http://www.dianping.com");
 2         HttpURLConnection huc = (HttpURLConnection)url.openConnection();
 3         huc.setRequestMethod("GET");
 4         huc.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36");
 5         BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream(),"UTF-8"));
 6           String msg = null;
 7           while(null!=(msg=br.readLine())) {
 8               System.out.println(msg);
 9           }
10           br.close();
11         }
View Code

  UDP编程:

每个数据发送单元被统一封装成数据包的方式,发送方将数据包发送到网络中,数据包在网路中去寻找他的目的地。

发送端:

1.使用DatagramSocket指定端口,创建发送端

2.准备数据,转成字节数组

3.封装成DatagramPacket包裹,需要指定目的地

4.发送包裹send(DatagramPacket 对象名称)

5.释放资源

 1 System.out.println("发送方启动中...");
 2     //指定端口,创建发送端
 3     DatagramSocket client = new DatagramSocket(8888);
 4     //将要发送的内容转化为字节数组
 5     String data = "努力学习";
 6     byte[] datas = data.getBytes();
 7     //封装成为DatagramPacket包裹,并指定目的地端口
 8     DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",9999));
 9     //发送包裹
10     client.send(packet);
11     //释放资源
12     client.close();
View Code

接收端:

1.使用DatagramSocket指定端口,创建接收端

2.准备容器,封装成DatagramPacket包裹

3.阻塞式接受包裹receive(DatagramPacket 对象名称)

4.分析数据 byte[ ] getData()   getLength()

5.释放资源

 1 System.out.println("接收方启动中...");
 2         //指定端口,创建接收端
 3         DatagramSocket server = new DatagramSocket(9999);
 4         //准备一个容器,并封装成为DatagramPacket包裹
 5         byte[] container = new byte[1024*60];
 6         DatagramPacket packet = new DatagramPacket(container,0,container.length);
 7         //阻塞式接收包裹
 8         server.receive(packet);
 9         //分析数据
10         byte[] datas = packet.getData();
11         int length = packet.getLength();
12         System.out.println(new String(datas,0,length));
13         //释放资源
14         server.close();
View Code

基本类型数据的发送:

第二步替换为:创建ByteArrayOutputStream流,用DataOutputStream流写入需要发送的内容。将ByteArrayOutputStream流用toByteArray()转化为字节数组。

 1 System.out.println("发送方启动中...");
 2         //指定端口,创建发送端
 3         DatagramSocket client = new DatagramSocket(8888);
 4         //将要发送的内容转化为字节数组
 5         ByteArrayOutputStream baos= new ByteArrayOutputStream();
 6         DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
 7         dos.writeUTF("努力学习");
 8         dos.writeInt(18);
 9         dos.writeBoolean(false);
10         dos.writeChar('a');
11         dos.flush();
12         byte[] datas = baos.toByteArray();//转化为字节数组
13         //封装成为DatagramPacket包裹,并指定目的地端口
14         DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",9999));
15         //发送包裹
16         client.send(packet);
17         //释放资源
18         client.close();
19         baos.close();
20         dos.close();
21         
View Code

基本类型数据的接收:

第四步替换为:创建ByteArrayOutputStream流,用getData()方法读出数据包中的数据。用DataInputStream流将数据存入,再用readxxx()方法读到各自数据类型变量中,最后打印即可。

 1 System.out.println("接收方启动中...");
 2         //指定端口,创建接收端
 3         DatagramSocket server = new DatagramSocket(9999);
 4         //准备一个容器,并封装成为DatagramPacket包裹
 5         byte[] container = new byte[1024*60];
 6         DatagramPacket packet = new DatagramPacket(container,0,container.length);
 7         //阻塞式接收包裹
 8         server.receive(packet);
 9         //分析数据
10         DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(packet.getData())));//读出基本类型
11         String msg = dis.readUTF();
12         int age = dis.readInt();
13         Boolean flag = dis.readBoolean();
14         char ch = dis.readChar();
15         System.out.println(msg);
16         System.out.println(age);
17         System.out.println(flag);
18         System.out.println(ch);
19         //释放资源
20         server.close();
21         dis.close();
View Code

   UTP编程:

创建服务器:

1.指定端口,使用ServerSocket创建服务器。

2.阻塞式等待accept。

3.操作:输入输出流操作。

4.释放资源。

创建客户端:

1.创建Scoket对象,指定要连接的服务器的IP和端口

2.获取scoket的输入流,并使用缓冲流进行包装

3.接收服务器端发送的信息

4.关闭流及socket连接

 

 

posted @ 2020-04-10 00:00  菅兮徽音  阅读(220)  评论(0编辑  收藏  举报