# 1.1、概述

** 地球村:** 你在西安,你一个美国的朋友!


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

网络编程的目的:
无线电台... 传播交流信息,数据交换。通信

想要达到这个效果需要什么:

  1. 如何准确定位网络上的一台主机:192.168.16.124:端口,定位到这个计算机上的某个资源
  2. 找到了这个主机,如何传输数据呢?

javaweb:网页编程 B/S
网络编程:TCP/IP C/S

# 1.2、网络通信的要素


如何实现网络的通信?
通信双方地址:

  • ip
  • 端口号
  • 192.168.16.124:5900

规则:网络通信协议
TCP/IP 参考模型
image.png
image.png
小结:

  1. 网络编程中有两个主要的问题
    • 如何准确的定位到网络上的一台或者多台主机
    • 找到主机之后如何进行通信
  2. 网络编程中的要素
    • IP 和端口号 IP.
    • 网络通信协议 udp,tcp
  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 fe80:aef0:9d3b:9daa:efce:adaa:10aa:af00 , 128 位。8 个无符号整数!
    • 公网(互联网) - 私网(局域网)
      • 192.168.xx.xx,专门给组织内部使用的
  • 域名:记忆 IP 问题
    • IP:www.vip.com
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
/**
 * 测试 IP
 * @author Pretend
 */
public class TestInetAddress {
    public static void main(String[] args) {
        try {
            // 查询本机地址
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            System.out.println(inetAddress1);
            InetAddress inetAddress3 = InetAddress.getByName("localhost");
            System.out.println(inetAddress3);
            InetAddress inetAddress4 = InetAddress.getLocalHost();
            System.out.println(inetAddress4);
            // 查询网站 ip 地址
            InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress2);
            // 常用方法
            //System.out.println(inetAddress2.getAddress());
            // 规定的名字
            System.out.println(inetAddress2.getCanonicalHostName());
            //ip
            System.out.println(inetAddress2.getHostAddress());
            // 域名,或者自己电脑的名字
            System.out.println(inetAddress2.getHostName());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

# 1.4、端口


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

  • 不同的进程有不同的端口号!用来区分软件的!
  • 被规定 0 ~ 65535
  • TCP,UDP:65535 * 2 tcp:80,udp:80,单个协议下,端口号不能冲突
  • 端口分类
    • 公有端口 0 ~ 1023
      • HTTP :80
      • HTTPS :443
      • FTP :21
      • Telent :23
    • 程序注册端口:2014 ~ 49151,分配用户或者程序
      • Tomcat :8080
      • MySql :3306
      • Oracle :1521
    • 动态、私有:49152 ~ 65535
netstat -ano #查看所有的端口
netstat -ano|findstr "5900" #查看指定的端口
tasklist|findstr "8312" #查看指定端口的进程

# 1.5、通信协议


协议:约定,就好比我们现在说的是普通话。
** 网络通信协议:** 速率,传输码率、代码结构、传输控制......
** 问题:** 非常的复杂?
大事化小:分层!
TCP/IP 协议簇:实际上是一组协议
重要:

  • TCP:用户传输协议
  • UDP:用户数据报协议

# TCP UDP 对比

TCP:打电话

  • 连接,稳定
  • 三次握手 四次挥手

image.png
image.png

最少需要三次,保证稳定连接!
(三次连接)
A:你瞅啥?
B:瞅你咋地?
A:干一场!
(四次断开)
A:我要走了!
B:我真的要走了吗?
B:你真的真的要走了吗?
A:我的真的要走了
  • 客户端、服务端
  • 传输连接,释放连接,效率低

UDP:发短信

  • 不连接,不稳定
  • 客户端、服务的:没有明确的界限
  • 不管有没有准备好,都可以发给你..

# 1.6、TCP


# 客户端

  1. 连接服务器 Socket
  2. 发送消息
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
 * 客户端
 * @author Pretend
 */
public class TcpClientDemo01 {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;
        try {
            //1. 要知道服务器的地址 端口号
            InetAddress serverIp = InetAddress.getByName("127.0.0.1");
            int port = 9999;
            //2. 创建一个 socket 连接
            socket = new Socket(serverIp, port);
            //3. 发送消息 IO 流
            System.out.println("请输入要要发送的内容:");
            os = socket.getOutputStream();
            os.write(new Scanner(System.in).next().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. 建立服务的端口 ServerSocket
  2. 等待用户的连接 accept
  3. 接受用户的消息
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 服务端
 *
 * @author Pretend
 */
public class TcpServerDemo01 {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1. 我得有一个地址
            serverSocket = new ServerSocket(9999);
            //2. 等待客户端连接过来
            socket = serverSocket.accept();
            //3. 读取客户端的消息
            is = socket.getInputStream();
            // 管道流
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            System.out.println("服务端已接收:");
            System.out.println(baos.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

# 文件上传

# 客户端

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
 * 客户端
 * @author Pretend
 */
public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        //1. 创建一个 Socket 连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
        //2. 创建输出流
        OutputStream os = socket.getOutputStream();
        //3. 读取文件
        FileInputStream fis = new FileInputStream(new File("E:\\壁纸\\6ffc8368d9c71d477f85a8bc5c3e5fa4.jpg"));
        //4. 写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            os.write(buffer,0,len);
        }
        // 通知服务器,已经传输完成了
        socket.shutdownOutput();
        // 确定服务器接受完毕,才能够断开连接
        InputStream is = socket.getInputStream();
        //String byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while ((len = is.read(buffer)) != -1) {
            baos.write(buffer,0,len);
        }
        System.out.println(baos.toString());
        //5. 关闭资源
        fis.close();
        os.close();
        socket.close();
    }
}

# 服务器端

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 服务端
 * @author Pretend
 */
public class TcpServerDemo02 {
    public static void main(String[] args) throws IOException {
        //1. 创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        //2. 监听客户端的连接 阻塞式监听,会一直等待客户端连接
        Socket socket = serverSocket.accept();
        //3. 获取输入流
        InputStream is = socket.getInputStream();
        //4. 文件输出
        FileOutputStream fos = new FileOutputStream(new File("E:\\壁纸\\1233.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            fos.write(buffer,0,len);
        }
        // 通知客户端接受完毕了
        OutputStream os = socket.getOutputStream();
        os.write("接收完毕!".getBytes());
        // 关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

# Tomcat

服务端

  • 自定义 S
  • Tomcat 服务器 S

客户端

  • 自定义 C
  • 浏览器 B

# 1.7、UDP


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


# 发送消息

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
 * 不再需要连接服务器
 * @author Pretend
 */
public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        //1. 建立一个包 Socket
        DatagramSocket socket = new DatagramSocket();
        //2. 建个包
        String msg = "你好啊,服务器!";
        // 发送给谁
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        // 数据,数据的长度起始,要发送给谁
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
        //3. 发包
        socket.send(packet);
        //4. 关闭流
        socket.close();
    }
}

# 接收端

import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
 * 服务器端
 * 还是要等待客户端的连接
 * @author Pretend
 */
public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception {
        //1. 开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //2. 接收数据包
        byte[] buffer = new byte[1024];
        // 接受
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        // 阻塞接收
        socket.receive(packet);
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0, packet.getLength()));
        // 关闭连接
        socket.close();
    }
}

# 循环发送消息

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
 * 不再需要连接服务器
 * @author Pretend
 */
public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        //1. 建立一个包 Socket
        DatagramSocket socket = new DatagramSocket();
        //2. 建个包
        String msg = "你好啊,服务器!";
        // 发送给谁
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        // 数据,数据的长度起始,要发送给谁
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
        //3. 发包
        socket.send(packet);
        //4. 关闭流
        socket.close();
    }
}

# 1.8、URL


https://www.baidu.com/
统一资源定位符:定位资源的,定位互联网上的某一个资源


DNS 域名解析 www.baidu.com xxx.x.x.x

协议://ip地址:端口/项目名/资源

# 读取网络资源

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class UrlDemo1 {
    public static void main(String[] args) throws IOException {
        //1.  地址
        URL url = new URL("https://www.baidu.com");
        //2.  连接到这个资源 HTTP
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        
        InputStream inputStream = urlConnection.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1) {
            baos.write(buffer,0,len);
        }
        System.out.println(baos);
    }
}
更新于 阅读次数