了解网络编程

什么是网络编程?

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

网络编程的目的:

  1. 传播交流信息。
  2. 数据交换。
  3. 通信。

如何达到此效果?

  1. 需要准确的定位网络上的一台主机,例如:192.168.25.31:port(端口)
  2. 找到主机传输数据。

网络编程&Javaweb

Javaweb:网页编程 ——>B/S

网络编程: TCP/IP ——>C/S

B/S和C/S的区别

  • 网络:
    • C/S建立在专用网络上,通过专门服务器服务
    • B/S建立在广域网上,不必有专门的网络硬件环境。
  • 群体:
    • C/S一般面向相对固定的用户群,对信息安全的控制能力很强。
    • B/S面向不可知的用户群,对安全的控制能力相对弱。

网络通信要素:

  1. IP地址

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

    • 本质上所有的网络访问是通过ip地址访问的,域名是一个速记符号,不用记住IP地址复杂的数字。

    • IP分类:

      • IPV4/IPV6:
        • IPV4:本地ip:127.0.0.1,主机名:localhost。
        • IPV6:128位,8个无符号整数。
      • 公网(互联网),私网(局域网):
      • 域名,代理公网IP的东西。比如我自己的博客JAUX 署记
        • 帮助记忆,比起一个难以记住的公网IP,域名的出现更容易去记忆。
  2. 端口号

    • 端口号用来标识进程的逻辑地址,不同进程的标识。

    • 端口有效范围:0~65535。

    • 分类:

      • 公有端口:

        • HTTP端口:80.
        • HTTPS端口:443.
        • FTP:21.
        • SSH:22.
        • Telent:23.
      • 程序注册端口:

        • Tomcat/bt(宝塔):8080.
        • MySQL:3306.
    • Oracle:1521.

  • 动态、私有:49152~65535.

       netstat -ano #查看所有端口
       netstat -ano|findstr "端口号" #查看指定端口
       tasklist|findstr "12748" #查看指定端口进程
    
  • 开发中不要使用1024以下的端口,即(0~1024)

  • 端口的作用:

    • 一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区 分不同的服务的。(也就是说一个端口号对应一个服务。)
  1. 传输协议

    • UDP(用户数据报协议

      1. 面向无连接的协议。
      2. 只管发送,不确认对方是否接收到。
        • 你和你的小妹妹VX聊天,你不需要她的同意发送消息给她,你只管发送就行,收不收的到是她的事。
      3. 将数据及源和目的封装 成数据包中,不需要建立连接。
      4. 每个数据报的大小限制在64K之内。
      5. 因为无需连接,因此是不可靠协议。
      6. 不需要建立连接,速度快。
    • TCP(Transmission Control Protocol,传输控制协议

      1. 面向连接的协议。

      2. 建立连接,形成传输数据的通道。

      3. 在连接中进行大数据传输(数据大小不受限制)。

      4. 通过三次握手,四次挥手完成连接,是可靠协议,安全送达。

        • 比如你早上睡醒不想起来买饭,然后你就想请求(一次)室友帮你带饭,你室友听到了要你喊爸爸才答应(两次),最终在你被迫的情况下他去帮你买饭(三次),可能比喻不太恰当😃

        • 假期回家,你对朋友说:“我回家了,不要太想念爸爸”(一次)。朋友:”真要回家?那可太好了!”(二次)。你:“不开玩笑!真走,得好几天见不到儿子了。”(三次)。朋友:“滚滚滚!有多远滚多远!!!”(四次)。

          Threadhand

      5. 必须建立连接,效率会稍低。

测试IP

查询本机地址:

public class Innet01 {
    public static void main(String[] args) {
        try {
            //本机地址
            InetAddress ip01 = InetAddress.getByName("127.0.0.1");
            System.out.println(ip01);
            InetAddress ip02 = InetAddress.getByName("localhost");
            System.out.println(ip02);
            InetAddress ip03 = InetAddress.getLocalHost();
            System.out.println(ip03);

        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

查询网络IP以及常用方法:

public class Innet01 {
    public static void main(String[] args) {
        try {
            //网络IP地址
            InetAddress ip04 = InetAddress.getByName("www.baidu.com");
            System.out.println(ip04);
            //常用方法
            System.out.println(ip04.getAddress());
            System.out.println(ip04.getCanonicalHostName());
            System.out.println(ip04.getHostAddress());
            System.out.println(ip04.getHostName());


        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

端口

测试:

public class Innet02 {
    public static void main(String[] args) {
        InetSocketAddress localhost = new InetSocketAddress("www.baidu.com", 8080);
        System.out.println(localhost);
        System.out.println("==========================");
        //常用代码
        System.out.println(localhost.getAddress());
        System.out.println(localhost.getHostName());
        System.out.println(localhost.getPort());
    }
}

image-20210408184855647

TCP应用

简单发送消息

客户端:

  1. 连接服务器Socket。

  2. 发送消息。

    public class TCPClients {
        public static void main(String[] args){
            Socket socket = null;
            OutputStream os = null;
            //获取服务器地址,端口号
            InetAddress severIP = null;
            try {
                severIP = InetAddress.getByName("127.0.0.1");
                int port = 8888;
                //创建一个socket连接
                socket = new Socket(severIP,port);
                //发送消息,IO流
                os = socket.getOutputStream();
                os.write("Hello, my son".getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if (os != null){
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

服务端:

  1. 建立服务端口SeverSocket。

  2. 等待用户连接accept。

  3. 接收用户消息。

    public class TCPSever {
        public static void main(String[] args) {
            ServerSocket serveIP = null;
            Socket accept = null;
            InputStream is = null;
            ByteOutputStream bous = null;
            try {
                //服务器端得有一个地址
                serveIP = new ServerSocket(8888);
                while (true){
                    //等待客户端连接
                    accept = serveIP.accept();
                    //获取客户端信息
                    is = accept.getInputStream();
    
                    //管线流
                    bous = new ByteOutputStream();
                    byte[] bt = new byte[1024];
                    int length;
                    while ((length = is.read(bt))!= -1){
                        bous.write(bt,0,length);
                    }
                    System.out.println(bous.toString());
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (bous != null){
                    bous.close();
                }
                if (is != null){
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (accept != null){
                    try {
                        accept.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (serveIP != null){
                    try {
                        serveIP.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

上传图片

客户端:

  1. 连接服务器Socket。

  2. 读取文件地址。

  3. 创建文件输入

    //客户端
    public class TCPIMGClients {
        public static void main(String[] args) throws Exception {
            //创建一个Socket连接
            Socket s = new Socket(InetAddress.getByName("127.0.0.1"),9999);
            //创建输出流
            OutputStream outp = s.getOutputStream();
            //创建文件输入流
            FileInputStream fos = new FileInputStream(new File("bilibili.jpg"));
            //写出文件
            byte[] bos = new byte[1024];
            int length;
            while ((length = fos.read(bos)) != -1){
                outp.write(bos,0,length);
            }
    
            //接收服务端结束
            InputStream inputStream = s.getInputStream();
            //String byte[]
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
            byte[] buffer = new byte[1024];
            int length2;
            while ((length2 = inputStream.read(buffer)) != -1){
                baos.write(buffer,0,length2);
            }
            System.out.println(baos.toString());
    
            //关闭资源
            fos.close();
            inputStream.close();
            outp.close();
            s.close();
        }
    }
    

服务端:

  1. 创建端口。

  2. 监听客户端连接。

  3. 获取文件输入。

  4. 下载文件。

    //服务端
    public class TCPIMGService {
        public static void main(String[] args) throws IOException {
            //创建服务
            ServerSocket serverSocket = new ServerSocket(9999);
            //监听客户端连接
            Socket accept = serverSocket.accept();
            //获取输入流
            InputStream is = accept.getInputStream();
            //文件输出
            FileOutputStream fouss = new FileOutputStream(new File("123.jpg"));
            byte[] bytes = new byte[1024];
            int length;
            while ((length = is.read(bytes)) != -1){
                fouss.write(bytes,0,length);
            }
            //通知客户端结束
            OutputStream os = accept.getOutputStream();
            os.write("我运行完毕,你可以滚蛋了".getBytes());
    
            //关闭资源
            fouss.close();
            is.close();
            accept.close();
            serverSocket.close();
        }
    }
    

Q.E.D.