Java网络编程入门

1. 初始网络编程

1.1 什么是网络编程?

网络编程就是让不同电脑上的程序能够互相通信。

  • 单机程序:自己跟自己玩
  • 网络程序:可以跟别人玩
1.2 网络编程能做什么?
应用例子
即时通讯微信、QQ
文件传输百度网盘、FTP
远程控制向日葵、TeamViewer
Web服务浏览器访问网站

2. 网络编程三要素

要素作用类比
IP地址找到哪台电脑小区地址
端口号找到电脑上哪个程序门牌号
协议数据怎么传快递规则

3. IP地址

3.1 什么是IP?

IP地址是网络中每台电脑的唯一标识。

IPv4:

  • 32位,4个字节
  • 格式:192.168.1.1
  • 最大数量:约42亿个(实际不够用)

解决:利用局域网IP解决IP不够的问题

IPv6:

  • 128位,16个字节
  • 格式:2001:0db8:85a3:0000:0000:8a2e:0370:7334
  • 数量:多到地球上每粒沙子都能分配一个
3.2 IPv4的小细节

特殊IP:

IP地址含义
127.0.0.1本机地址(localhost)
0.0.0.0所有网卡地址
255.255.255.255广播地址

私有IP(内网使用,不能上网):

  • 10.0.0.0 ~ 10.255.255.255
  • 172.16.0.0 ~ 172.31.255.255
  • 192.168.0.0 ~ 192.168.255.255
3.3 InetAddress类的使用
public static void main(String[] args) throws UnknownHostException {

    static InetAddress getByName(String host) // 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
    String getHostName()     // 获取此IP地址的主机名
    String getHostAddress()  // 返回文本显示中的IP地址字符串

    //1. 获取InetAddress的对象
    //IP的对象  一台电脑的对象
    InetAddress address = InetAddress.getByName("DESKTOP-503JSAM");
    System.out.println(address);

    String name = address.getHostName();
    System.out.println(name); // DESKTOP-503JSAM

    String ip = address.getHostAddress();
    System.out.println(ip); // 192.168.1.100
}


4. 端口号

4.1 什么是端口?

电脑上同时运行很多程序,数据到了之后该给谁?

端口号就是程序在网络中的门牌号。

一个端口对应一个应用

4.2 端口范围
  • 0 ~ 65535(共65536个)
  • 0 ~ 1023:系统保留端口
  • 1024 ~ 49151:注册端口
  • 49152 ~ 65535:动态/私有端口
4.3 常用端口
端口协议用途
80HTTP网页访问
443HTTPS安全网页
21FTP文件传输
22SSH安全远程登录
3306MySQL数据库

5. 协议

5.1 TCP vs UDP
维度TCPUDP
连接需要建立连接不需要
可靠性可靠,不丢数据不可靠,可能丢
顺序按顺序到达可能乱序
速度慢快
应用文件下载、网页视频通话、直播

比喻:

  • TCP = 打电话(先接通,再说话)
  • UDP = 写信(扔邮筒里,不管收不收得到)
5.2 三次握手(TCP建立连接)
客户端                    服务器
  |                        |
  |------- SYN ---------->| (1) 客户端:我要连接
  |                        |
  |<----- SYN+ACK --------| (2) 服务器:好的,你连吧
  |                        |
  |------- ACK ---------->| (3) 客户端:收到,开始传数据
  |                        |
5.3 四次挥手(TCP断开连接)
客户端                    服务器
  |                        |
  |------- FIN ---------->| (1) 客户端:我发完了
  |                        |
  |<------ ACK -----------| (2) 服务器:知道了
  |                        |
  |<------ FIN -----------| (3) 服务器:我也发完了
  |                        |
  |------- ACK ---------->| (4) 客户端:好的,再见
  |                        |

6. UDP协议

6.1 UDP发送数据
//发送数据

//1.创建DatagramSocket对象(快递公司)
//细节:
//绑定端口,以后我们就是通过这个端口往外发送
//空参:所有可用的端口中随机一个进行使用
//有参:指定端口号进行绑定
DatagramSocket ds = new DatagramSocket();

//2.打包数据
String str = "你好啊!!!";
byte[] bytes = str.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 10086;

DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);

//3.发送数据
ds.send(dp);

//4.释放资源
ds.close();
6.2 UDP接收数据
//1.创建DatagramSocket对象(快递公司)
//细节:
//在接收的时候,一定要绑定端口
//而且绑定的端口一定要跟发送的端口保持一致
DatagramSocket ds = new DatagramSocket(10086);

//2.接收数据包
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);

//3.解析数据包
byte[] data = dp.getData();
int len = dp.getLength();
InetAddress address = dp.getAddress();
int port = dp.getPort();

System.out.println("接收到数据" + new String(data, 0, len));
System.out.println("该数据是从" + address + "这台电脑中的" + port + "这个端口发出的");

//4.释放资源
ds.close();

6.3 UDP单播、组播、广播
类型说明目标
单播一对一特定一个IP
组播一对多(加入组)组播地址(224.0.0.0 ~ 239.255.255.255)
广播一对所有255.255.255.255
// 广播示例:发送到广播地址
DatagramPacket packet = new DatagramPacket(data, data.length, 
    InetAddress.getByName("255.255.255.255"), 8888);

组播:

public class SendMessageDemo {
    public static void main(String[] args) throws IOException {
        /*
        组播发送端代码
        */
        //创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket();

        // 创建DatagramPacket对象
        String s = "你好,你好!";
        byte[] bytes = s.getBytes();
        InetAddress address = InetAddress.getByName("224.0.0.1");
        int port = 10000;

        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, address, port);

        // 调用MulticastSocket发送数据方法发送数据
        ms.send(datagramPacket);

        // 释放资源
        ms.close();
    }
}
public class ReceiveMessageDemo1 {
    public static void main(String[] args) throws IOException {
        /*
         * 组播接收端代码
        */

        //1. 创建MulticastSocket对象
        MulticastSocket ms = new MulticastSocket(10000);

        //2. 将当前本机,添加到224.0.0.1的这一组当中
        InetAddress address = InetAddress.getByName("224.0.0.1");
        ms.joinGroup(address);

        //3. 创建DatagramPacket数据包对象
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

        //4. 接收数据
        ms.receive(dp);

        //5. 解析数据
        byte[] data = dp.getData();
        int len = dp.getLength();
        String ip = dp.getAddress().getHostAddress();
        String name = dp.getAddress().getHostName();

        System.out.println("ip为: " + ip + ",主机名为: " + name + "的人。发送了数据: " + new String(data, 0, len));

        //6. 释放资源
        ms.close();
    }
}

7. TCP协议

7.1 TCP发送数据
public class Client {
    static void main() throws IOException {
        //创建Socket对象
        Socket socket = new Socket("192.168.1.79", 10086);
		//获取输入流
        OutputStream os = socket.getOutputStream();
        os.write("hi".getBytes());
		//关闭
        os.close();
        socket.close();
    }
}
7.2 TCP接收数据
public class Server {
    static void main() throws IOException {
        //创建ServerSocket对象
        ServerSocket ss = new ServerSocket(10086);
		//监听客户端连接
        Socket socket = ss.accept();
        //获取输出流
        InputStream is = socket.getInputStream();
        int b;
        while((b = is.read()) != -1){
            System.out.println((char) b);
        }
        //关闭
        socket.close();
        ss.close();
    }
}
7.3 中文乱码问题

字节流直接处理中文可能乱码,用转换流解决:

//获取输出流
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
int b;
while((b = isr.read()) != -1){
	System.out.println((char) b);
}

8. 网络编程架构:C/S 和 B/S

8.1 C/S架构(Client-Server,客户端/服务器)

特点:

  • 需要安装专门的客户端软件
  • 客户端和服务器都需要开发
  • 客户端可以分担计算压力

例子:微信、QQ、游戏、网络编程的Socket例子

┌────────┐                    ┌────────┐
│ 客户端1 │◄────网络──────────►│        │
└────────┘                    │ 服务器 │
┌────────┐                    │        │
│ 客户端2 │◄──────────────────►│        │
└────────┘                    └────────┘
8.2 B/S架构(Browser-Server,浏览器/服务器)

特点:

  • 客户端就是浏览器,无需安装
  • 只需要开发服务器
  • 更新方便(改服务器即可)

例子:淘宝、百度、B站

┌────────┐                    ┌────────┐
│ 浏览器1 │◄────HTTP──────────►│        │
└────────┘                    │ Web    │
┌────────┐                    │ 服务器 │
│ 浏览器2 │◄──────────────────►│        │
└────────┘                    └────────┘
8.3 C/S vs B/S 对比
维度C/SB/S
客户端需要安装只需要浏览器
更新每个客户端都要更新服务器更新即可
性能客户端可分担主要靠服务器
跨平台需要不同版本浏览器都支持
开发成本高(两端都要写)低(只写服务器)
用户体验更好依赖网络
学习内容Socket编程HTTP + Web框架

9. 常见异常及原因

异常原因
ConnectException服务器没启动或端口不对
BindException端口被占用
SocketTimeoutException连接或读取超时
UnknownHostException域名解析失败

10. 易错点总结

  1. 先启动服务端,再启动客户端

  2. 端口不要用1024以下(系统保留)

  3. UDP接收时,端口要和服务端绑定的端口一致

  4. TCP用字符流处理中文要加flush,否则数据不发送

  5. readLine需要换行符,发送端要加writer.newLine()

  6. 关闭资源要按顺序


11. 总结

知识点核心内容
IP地址找到电脑(InetAddress)
端口号找到程序(0~65535)
UDP无连接、不可靠、快(DatagramSocket)
TCP有连接、可靠、慢(Socket/ServerSocket)
C/S客户端+服务器,需安装
B/S浏览器+服务器,无需安装

更多推荐