前段时间出差,还有做一个Java商城的实战项目,花费了很多时间,没有进行系统的学习,今天来继续网络编程的学习。

学习Java的io流应用,和TCP、UDP的socket、package编程

网络编程

1.1 概述

打电话 -- 连接 -- 接了 --通话 TCP

发短信 -- 发送了就完事儿了 --接收 UDP

计算机网络,指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

 

网络编程的目的

无线电台...传播交流信息,数据交换,通信

 

想要达成这个效果需要什么?

  1. 如何准确的定位网络上的一台主机,IP地址:端口,定位到这个计算机上的某个资源

  2. 找到了这个主机,如何传输数据?

 

网页编程:JavaWeb B/S架构

网络编程:TCP/IP C/S架构

 

1.2 网络通信的要素

如何实现网络的通信?

通信双方地址:

  • IP地址 192.168.1.1

  • 端口号 :8080

  • 192.168.1.1:8080

规则:网络通信协议

TCP/IP参考模型

OSI七层网络模型TCP/IP四层概念模型对应网络协议
应用层 应用层 HTTP、TFTP、FTP、NFS、WAIS、SMTP
表示层 应用层 Telnet、Rlogin、SNMP、Gopher
会话层 应用层 SMTP、DNS
传输层 传输层 TCP、UDP
网络层 网络层 IP、ICMP、ARP、RARP、AKP、UUCP
数据链路层 数据链路层 FDDI、Ethernet、Arpanet、PDN、SLIP、PPP
物理层 数据链路层 IEEE 802.1A、IEEE 802.2到IEEE 802.11

小结:

  1. 网络编程中有两个主要的问题

    • 如何准确的定位到网络上的一台或者多台主机

    • 找到主机之后如何进行通信

  2. 网络编程中的要素

    • IP地址和端口号

    • 网络通信协议

  3. 万物皆对象

1.3 IP

IP地址:InetAddress

  • 唯一定位一台网络上计算机

  • 127.0.0.1:本机localhost

  • IP地址的分类

    • IPv4/IPv6

      • IPv4 127.0.0.1,4个字节组成,0~255,有42亿个左右;30亿在北美,亚洲只有4亿,2011年已经用尽

      • IPv6 可以使用cmd命令ipconfig查看,有128位,8个无符号整数

C:\Users\88534>ipconfig

Windows IP 配置


以太网适配器 VirtualBox Host-Only Network:

  连接特定的 DNS 后缀 . . . . . . . :
  本地链接 IPv6 地址. . . . . . . . : fe80::fc60:729c:8420:ee91%14
  IPv4 地址 . . . . . . . . . . . . : 192.168.56.1
  子网掩码 . . . . . . . . . . . . : 255.255.255.0
  默认网关. . . . . . . . . . . . . :

无线局域网适配器 本地连接* 1:

  媒体状态 . . . . . . . . . . . . : 媒体已断开连接
  连接特定的 DNS 后缀 . . . . . . . :

无线局域网适配器 本地连接* 2:

  媒体状态 . . . . . . . . . . . . : 媒体已断开连接
  连接特定的 DNS 后缀 . . . . . . . :

无线局域网适配器 WLAN:

  连接特定的 DNS 后缀 . . . . . . . :
  本地链接 IPv6 地址. . . . . . . . : fe80::81a3:fbe4:4431:e509%19
  IPv4 地址 . . . . . . . . . . . . : 192.168.1.4
  子网掩码 . . . . . . . . . . . . : 255.255.255.0
  默认网关. . . . . . . . . . . . . : 192.168.1.1
  • 公网(互联网)/私网(局域网)

    • ABCD类地址8、16、24位+多=组播地址

    • 192.168.xx.xx专门给组织内部使用

    • 0-----------------------128--------192--------255

  • 域名:便于记忆


1.4 端口

端口表示计算机上的一个程序的进程

  • 不同的进程有不同的端口号,用来区分软件

  • 被规定0~65535

     1 package com.zhou.networkCode;
     2  3 import java.net.InetAddress;
     4 import java.net.UnknownHostException;
     5  6 //测试IP
     7 public class TestInetAddress {
     8     public static void main(String[] args) {
     9         try {
    10             //查询本机地址
    11             InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");//localhost、getLocalHost()
    12             System.out.println(inetAddress1);
    13 14             //查询网站IP地址
    15             InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
    16             System.out.println(inetAddress2);
    17 18             //常用方法
    19             System.out.println(inetAddress2.getAddress());//[B@1b6d3586
    20             System.out.println(inetAddress2.getHostAddress());//183.232.231.174     ip
    21             System.out.println(inetAddress2.getCanonicalHostName());//www.baidu.com     规范的名字
    22             System.out.println(inetAddress2.getHostName());//www.baidu.com      域名,或者自己电脑的名字
    23             
    24         } catch (UnknownHostException e) {
    25             e.printStackTrace();
    26         }
    27     }
    28 }

     

  • TCP/UDP:65535*2,每个协议都有一组。可以分别使用同一端口不同协议。 tcp:80,udp:80.在单个协议下,端口号不能冲突

  • 端口分类

    • 公有端口:0~1023

      • HTTP:80

      • HTTPS:443

      • FTP:21

      • SSH:22

      • Telnet:23

    • 程序注册端口:2014~49151,分配用户或者程序

      • Tomcat:8080

      • MySQL:3306

      • Oracle:1521

    • 动态、私有:49152~65535

    netstat -ano #查看所有的端口
    netstat -ano|findstr "5900" #查看指定的端口
    tasklist|findstr "8696" #查看指定端口的进程
    ctrl+shift+ESC #打开任务管理器,查看进程

1.5 通信协议

协议:约定,大家共同使用的方法

网络通信协议:速度,传输码率、代码结构、传输控制...

大事化小:采用分层的概念

TCP/IP协议簇:实际上是一组协议

  • TCP簇:用户传输协议

  • IP簇:用户数据报协议

出名的协议:

  • TCP:传输控制协议

  • IP:网络互联协议

TCP/UDP对比

TCP:打电话

  • 连接,稳定

  • 三次握手,四次挥手

    • 最少需要三次,保证稳定连接

    • A:你瞅啥?

    • B:瞅你咋地?(建立B->A)

    • A:干一场!(建立A->B)

    •  

    • A:我要走了

    • B:我知道了(断开A->B)

    • B:我也要走了

    • A:好的,我知道你要走了(断开B->A)

  • 客户端、服务端

  • 传输完成,释放连接,传输可靠,效率低

UDP:发短信

  • 不连接,不稳定

  • 客户端、服务端:没有明确的界限

  • 不管有没有准备好,都发

  • DDOS:洪水攻击,饱和攻击

1.6 TCP

服务器

  1. 连接服务器Socket

  2. 发送消息

客户端

  1. 建立服务的端口ServerSocket

  2. 等待用户的链接accept

  3. 接收消息

简单通信

服务器端先执行

 1 package com.zhou.networkCode;
 2  3 import java.io.ByteArrayOutputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.net.ServerSocket;
 7 import java.net.Socket;
 8  9 public class TcpServerDemo01 {
10     //先运行服务器端Server开启接受,再到运行客户端Client发送信息
11     public static void main(String[] args) {
12         ServerSocket serverSocket = null;
13         Socket socket = null;
14         InputStream is = null;
15         ByteArrayOutputStream baos = null;
16         try {
17             //1.我得有一个地址
18              serverSocket = new ServerSocket(9999);
19             //2.等待客户端连接过来
20              socket = serverSocket.accept();
21             //3.读取客户端的消息
22              is = socket.getInputStream();
23 24             /*
25             byte[] buffer = new byte[1024];
26             int len;
27             while ((len = is.read(buffer)) != -1) {
28                 String msg = new String((buffer, 0, len);
29                 System.out.println(msg);
30             }
31              */
32 33             //管道流
34             baos = new ByteArrayOutputStream();
35             byte[] buffer = new byte[1024];
36             int len;
37             while ((len = is.read(buffer)) != -1) {
38                 baos.write(buffer,0,len);
39             }
40             System.out.println(baos.toString());
41 42 43         } catch (Exception e) {
44             e.printStackTrace();
45         } finally {
46             //关闭资源
47             if (baos!=null){
48                 try {
49                     baos.close();
50                 } catch (IOException e) {
51                     e.printStackTrace();
52                 }
53             }
54             if (is!=null){
55                 try {
56                     is.close();
57                 } catch (IOException e) {
58                     e.printStackTrace();
59                 }
60             }
61             if (socket!=null){
62                 try {
63                     socket.close();
64                 } catch (IOException e) {
65                     e.printStackTrace();
66                 }
67             }
68             if (serverSocket!=null){
69                 try {
70                     serverSocket.close();
71                 } catch (IOException e) {
72                     e.printStackTrace();
73                 }
74             }
75         }
76     }
77 }

 


客户端后执行

 1 package com.zhou.networkCode;
 2  3 import java.io.IOException;
 4 import java.io.OutputStream;
 5 import java.net.InetAddress;
 6 import java.net.Socket;
 7  8 public class TcpClientDemo01 {
 9     public static void main(String[] args) {
10         Socket socket = null;
11         OutputStream os = null;
12         try {
13             //1.要知道服务器的地址
14             InetAddress serverIP = InetAddress.getByName("127.0.0.1");
15             int port = 9999;
16             //2.创建一个socket连接
17             socket = new Socket(serverIP,port);
18             //3.发送消息IO流
19             os = socket.getOutputStream();
20             os.write("你好!".getBytes());//发送信息
21         } catch (Exception e) {
22             e.printStackTrace();
23         } finally {
24             if (os!=null){
25                 try {
26                     os.close();
27                 } catch (IOException e) {
28                     e.printStackTrace();
29                 }
30             }
31             if (socket!=null){
32                 try {
33                     socket.close();
34                 } catch (IOException e) {
35                     e.printStackTrace();
36                 }
37             }
38         }
39     }
40 }

 

输出:你好

文件上传

服务器端

 1 package com.zhou.networkCode;
 2  3 import java.io.*;
 4 import java.net.ServerSocket;
 5 import java.net.Socket;
 6 import java.nio.charset.StandardCharsets;
 7  8 public class TcpServerDemo02 {
 9     public static void main(String[] args) throws IOException {
10         //1.创建服务
11         ServerSocket serverSocket = new ServerSocket(9000);
12         //2.监听客户端的连接
13         Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
14         //3.获取输入流
15         InputStream is = socket.getInputStream();
16         //4.文件输出
17         FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\88534\\Desktop\\Java入门\\NetWorkCode\\receive.jpg"));
18         byte[] buffer = new byte[1024];
19         int len;
20         while ((len=is.read(buffer))!=-1){
21             fos.write(buffer,0,len);
22         }
23         //通知客户端接收完毕
24         OutputStream os = socket.getOutputStream();
25         os.write("我接收完毕了,你可以断开了".getBytes());
26         //5.关闭资源
27         os.close();
28         fos.close();
29         is.close();
30         socket.close();
31         serverSocket.close();
32     }
33 }

 

客户端

 1 package com.zhou.networkCode;
 2  3 import java.io.*;
 4 import java.net.InetAddress;
 5 import java.net.Socket;
 6  7 public class TcpClientDemo02 {
 8     public static void main(String[] args) throws IOException {
 9         //1.建立一个socket连接
10         Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
11         //2.创建一个输出流
12         OutputStream os = socket.getOutputStream();
13         //3.文件流
14         FileInputStream fis = new FileInputStream(new File("C:\\Users\\88534\\Desktop\\Java入门\\NetWorkCode\\Java.jpg"));
15         //4.写出文件
16         byte[] buffer = new byte[1024];
17         int len;
18         while ((len=fis.read(buffer))!=-1){
19             os.write(buffer,0,len);
20         }
21         //通知服务器,已经传输完了
22         socket.shutdownOutput();
23         //确定服务器接收完毕,才能够断开连接
24         InputStream is = socket.getInputStream();
25         //String Array[]
26         ByteArrayOutputStream baos = new ByteArrayOutputStream();
27         byte[] buffer2 = new byte[1024];
28         int len2;
29         while ((len2=is.read(buffer2))!=-1){
30             baos.write(buffer2,0,len2);
31         }
32         System.out.println(baos.toString());
33         //5.关闭资源
34         baos.close();
35         is.close();
36         fis.close();
37         os.close();
38         socket.close();
39     }
40 }

 

1.7 Tomcat

服务器:Tomcat服务器

客户端:浏览器 B/S架构

打开bin目录下startup.bat(Windows下)/startup.sh(IOS下)打开服务器,开启8080端口,在webapp文件夹中放入网页信息

1.8 UDP

发短信:不需要连接,只需要知道对方的地址

发送消息

发送端

 1 package com.zhou.networkCode;
 2  3 import java.net.DatagramPacket;
 4 import java.net.DatagramSocket;
 5 import java.net.InetAddress;
 6  7 //不需要连接服务器
 8 public class UdpClientDemo01 {
 9     public static void main(String[] args) throws Exception{
10         //1.建立一个Socket
11         DatagramSocket socket = new DatagramSocket();
12 13         //2.建个包
14         String msg = "Hello,Server!";
15 16         //发送位置
17         InetAddress localhost = InetAddress.getByName("localhost");
18         int port = 9090;
19         //建立一个Packet
20         DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
21         //3.发送包
22         socket.send(packet);
23         //4.关闭流
24         socket.close();
25     }
26 }

 

接收端

 1 package com.zhou.networkCode;
 2 
 3 import java.net.DatagramPacket;
 4 import java.net.DatagramSocket;
 5 
 6 public class UdpServerDemo01 {
 7     public static void main(String[] args) throws Exception{
 8         //开放端口
 9         DatagramSocket socket = new DatagramSocket(9090);
10         //接收数据包
11         byte[] buffer = new byte[1024];
12         DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
13         socket.receive(packet);//阻塞接收
14 
15         System.out.println(packet.getAddress().getHostAddress());
16         System.out.println(new String(packet.getData(),0,packet.getLength()));
17         //关闭连接
18         socket.close();
19     }
20 }

 

输出:127.0.0.1

Hello,Server!

咨询

循环发送消息

 1 package com.zhou.networkCode;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.InputStreamReader;
 5 import java.net.DatagramPacket;
 6 import java.net.DatagramSocket;
 7 import java.net.InetSocketAddress;
 8 
 9 public class UdpSenderDemo01 {
10     public static void main(String[] args) throws Exception{
11         DatagramSocket socket = new DatagramSocket(8888);
12 
13         //准备数据:控制台读取System.in
14 
15         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
16 
17         while (true){
18             String data = reader.readLine();
19             byte[] datas = data.getBytes();
20             DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));
21 
22             socket.send(packet);
23             if (data.equals("bye")) {
24                 break;
25             }
26         }
27 
28         socket.close();
29     }
30 }

 

循环接收消息

 1 package com.zhou.networkCode;
 2 
 3 import java.net.DatagramPacket;
 4 import java.net.DatagramSocket;
 5 
 6 public class UdpReceiverDemo01 {
 7     public static void main(String[] args) throws Exception{
 8         DatagramSocket socket = new DatagramSocket(6666);
 9 
10         while (true){
11             //准备接收包裹
12             byte[] container = new byte[1024];
13             DatagramPacket packet = new DatagramPacket(container,0,container.length);
14 
15             //断开连接:检测输入bye
16             byte[] data = packet.getData();
17             String receiveData = new String(data, 0, data.length);
18 
19             System.out.println(receiveData);
20             if (receiveData.equals("bye")){
21                 break;
22             }
23 
24             socket.receive(packet);
25         }
26 
27 
28         socket.close();
29     }
30 }

 

在线咨询

使用多线程,既可以是接收方,又可以是发送方

发送端

 1 package com.zhou.networkCode;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.IOException;
 5 import java.io.InputStreamReader;
 6 import java.net.DatagramPacket;
 7 import java.net.DatagramSocket;
 8 import java.net.InetSocketAddress;
 9 
10 public class OnlineTalkSenderDemo01 implements Runnable{
11     DatagramSocket socket = null;
12     BufferedReader reader = null;
13 
14     private int fromPort;
15     private String toIP;
16     private int toPort;
17 
18     public OnlineTalkSenderDemo01(int fromPort, String toIP, int toPort) {
19         this.fromPort = fromPort;
20         this.toIP = toIP;
21         this.toPort = toPort;
22 
23         try {
24             socket = new DatagramSocket(fromPort);
25             reader = new BufferedReader(new InputStreamReader(System.in));
26         } catch (Exception e) {
27             e.printStackTrace();
28         }
29     }
30 
31     @Override
32      public void run() {
33 
34         while (true){
35             try {
36                 String data = reader.readLine();
37                 byte[] datas = data.getBytes();
38                 DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));
39 
40                 socket.send(packet);
41                 if (data.equals("bye")) {
42                     break;
43                 }
44             } catch (Exception e) {
45                 e.printStackTrace();
46             }
47         }
48         socket.close();
49     }
50 }

 

接收端

 1 package com.zhou.networkCode;
 2 
 3 import java.io.IOException;
 4 import java.net.DatagramPacket;
 5 import java.net.DatagramSocket;
 6 import java.net.SocketException;
 7 
 8 public class OnlineTalkReceiverDemo01 implements Runnable{
 9     DatagramSocket socket = null;
10     private int port;
11     private String msgFrom;
12 
13     public OnlineTalkReceiverDemo01(int port, String msgFrom) {
14         this.port = port;
15         this.msgFrom = msgFrom;
16         try {
17             socket = new DatagramSocket(port);
18         } catch (Exception e) {
19             e.printStackTrace();
20         }
21     }
22 
23     @Override
24     public void run() {
25         while (true){
26             try {
27                 //准备接收包裹
28                 byte[] container = new byte[100];
29                 DatagramPacket packet = new DatagramPacket(container,0,container.length);
30                 socket.receive(packet);
31 
32                 //断开连接:检测输入bye
33                 byte[] data = packet.getData();
34                 String receiveData = new String(data, 0, data.length);
35 
36                 System.out.println(msgFrom + ":" + receiveData);
37                 if (receiveData.equals("bye")){
38                     break;
39                 }
40 
41             } catch (Exception e) {
42                 e.printStackTrace();
43             }
44         }
45         socket.close();
46     }
47 }

 

用户1:学生->老师

package com.zhou.networkCode;

public class OnlineTalkStudent {
    public static void main(String[] args) {
        //开启两个线程
        new Thread(new OnlineTalkSenderDemo01(7777,"127.0.0.1",9999)).start();
        new Thread(new OnlineTalkReceiverDemo01(8888,"老师")).start();
    }
}

 

用户2:老师->学生

package com.zhou.networkCode;

public class OnlineTalkTeacher {
    public static void main(String[] args) {
        new Thread((new OnlineTalkSenderDemo01(5555,"localhost",8888))).start();
        new Thread(new OnlineTalkReceiverDemo01(9999,"学生")).start();
    }
}

 

1.8 URL

统一资源定位符:定位资源,可以定位互联网上的某一个具体资源

DNS为域名解析 域名->指代IP

协议://IP地址:端口/文件所在目录/文件名.文件类型

package com.zhou.networkCode;

import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo01 {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/helloWorld/index.jsp?username=zhou&password=123");
        System.out.println(url.getProtocol());//协议:http
        System.out.println(url.getHost());//主机ip:localhost
        System.out.println(url.getPort());//端口:8080
        System.out.println(url.getPath());//文件:/helloWorld/index.jsp
        System.out.println(url.getFile());//全路径:/helloWorld/index.jsp?username=zhou&password=123
        System.out.println(url.getQuery());//参数:username=zhou&password=123
    }
}

 

从Tomcat下载文件

打开startup.bat运行Tomcat打开8080端口

 1 package com.zhou.networkCode;
 2 
 3 import java.io.FileOutputStream;
 4 import java.io.InputStream;
 5 import java.net.HttpURLConnection;
 6 import java.net.MalformedURLException;
 7 import java.net.URL;
 8 
 9 public class URLDownload {
10     public static void main(String[] args) throws Exception {
11         //1.下载地址
12         URL url = new URL("http://localhost:8080/helloWorld/helloWorld.txt");
13         //2.连接到这个资源,用HTTP
14         HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
15         InputStream inputStream = urlConnection.getInputStream();
16         FileOutputStream fos = new FileOutputStream("HELLOWORLD.txt");
17         byte[] buffer = new byte[1024];
18         int len;
19         while ((len=inputStream.read(buffer))!=-1){
20             fos.write(buffer,0,len);//写出这个数据
21         }
22         fos.close();
23         inputStream.close();
24         urlConnection.disconnect();//断开连接
25     }
26 }

 

posted on 2021-08-03 12:35  zrm0612  阅读(38)  评论(0)    收藏  举报