第五章 网络编程 TCP/UDP/Socket

第五章 网络编程

一、IP地址

java 复制代码
唯一标识网络上的每一台计算机
32位,由4个8位二进制数组成
    

1.IP地址的组成

java 复制代码
IP地址 = 网络地址 +主机地址
网络地址:标识计算机或网络设备所在的网段
主机地址:标识特定主机或网络设备
    
A类地址通常分配给具有大量主机的网络使用A类地址:0.0.0.0---127.255.255.255

B类地址通常分配给规模中等的网络使用  B类地址:128.0.0.0---191.255.255.255

C类地址通常分配给小型局域网使用。C类地址:192.0.0.0---223.255.255.255,

A/B/C/D/E类 地址的组成

java 复制代码
查看本机的IP地址
ipconfig
测试网络是否通畅
ping  目标IP地址

二、DNS域名

java 复制代码
访问网站时,为什么输入网址而不是IP地址
    
1. 域名易于记忆
2. 域名与IP地址的动态绑定
网站的IP地址可能会随时改变,但域名不会改变。互联网服务提供商或网站管理员可以在后台更新IP地址,而用户只需继续访问相同的域名。
域名解析系统(DNS)充当了翻译器的角色。当用户在浏览器中输入域名时,DNS将该域名转换成实际的IP地址,从而帮助浏览器找到目标服务器。
3.负载均衡与多个IP地址
一个大型网站通常会使用多个服务器,每个服务器可能有不同的IP地址。通过一个域名
(如www.example.com),可以将用户请求动态地分配给多个服务器,以实现负载均衡,提升网站的响应速度和可靠性。如果用户直接输入IP地址,可能只访问其中一台服务器,影响了均衡分布的效果。
 

三、网络通信协议

简化后的五层协议

java 复制代码
1.物理层: 基于电路特性的高低电压(电信号)  高电压代表1 低电压代表0
2.数据链路层:  定义电信号的分组方式
3.网络层: 引入一套新的地址来区分不同的广播域
4.传输层: 端口到端口的连接通信
5.应用层: (应用层,表示层,会话层) 规定了数据的传输格式 ftp/http/www
java 复制代码
1. 局域网(LAN, Local Area Network)
特点:覆盖范围较小,通常在一个建筑物内或几百米范围内的网络。
用途:用于连接公司、学校、家庭等场所内的设备,以便实现资源共享、数据传输和通信。
示例:办公室内部的网络,家用Wi-Fi网络。
2. 城域网(MAN, Metropolitan Area Network)
特点:覆盖范围介于局域网和广域网之间,通常在一个城市范围内,连接多个局域网。
用途:用于连接城市中多个建筑物、企业、政府部门等,提供高速数据传输。
示例:一个城市的电信网络或大学校园网。
3. 广域网(WAN, Wide Area Network)
特点:覆盖范围广泛,通常在国家、洲际甚至全球范围内连接多个局域网和城域网。
用途:广泛用于跨城市、国家或国际的数据传输,互联网就是一种广域网。
示例:互联网,全球企业之间的数据通信网络。
4. 个人区域网(PAN, Personal Area Network)
特点:覆盖范围很小,通常在几米到十几米之间,用于个人设备之间的通信。
用途:用于个人设备(如智能手机、平板、耳机、手表等)之间的无线连接。
示例:蓝牙设备连接、手机热点。
5. 全球网(GAN, Global Area Network)
特点:覆盖全球范围,连接广域网的网络。其规模最大,涵盖地球范围内的网络。
用途:用于实现全球范围内的数据通信和信息传输。
示例:全球互联网服务供应商(ISP)构建的全球网络。

四、Socket

TCP协议

三次握手,四次挥手

java 复制代码
三次握手  建立通信
    A 客户端   B 服务器
  1.(A-->B)  携带syn 数据包
    A问B 你可以收到我的信息嘛
  2.(B--A)   携带syn+ack数据包
    b回答A 可以收到
  3.(A-->B)  收到了可以开始通信了
java 复制代码
四次挥手  断开联系
    1.(a-->b) 发送fin包 
    我要断开连接了
    2.(b-->a)   发送ack包 
    可以断开连接,进入断开等待状态
    3.(b--a)   发送fin包 
    我准备好了,可以断开链接了
    4.(a-->b)  发送ack包 
    A确定断开连接,发送数据包,b在接收到数据包时立刻断开连接,a进入超时等待状态,最后断开连接
java 复制代码
是 Java 网络编程中的核心类之一,用于实现基于 TCP/IP 协议的网络通信。
    Socket 提供了客户端和服务器之间的双向通信功能。通过 Socket,客户端可以连接到服务器,双方可以交换数据。
    通信链路的端点就被称为"套接字"(英文名Socket)
    是提供给应用程序的接口

常用的包:

Socket

ServerSocket

DatagramPacket

DatagramSocket

InetAddress

1.Socket/ServerSocket

java 复制代码
常用方法
    Socket 常用方法
socket():创建一个 Socket。
bind():将 Socket 绑定到本地的一个 IP 地址和端口。
listen():将 Socket 设置为监听模式,等待连接请求。
accept():接受客户端的连接请求。
connect():客户端用于连接到服务器。
send() 和 recv():用于在客户端和服务器之间发送和接收数据。
close():关闭 Socket 连接
java 复制代码
ServerSocket 是 Java 网络编程中的一个类,专门用于 服务器端 的通信。
    它用于监听特定端口上的客户端连接请求,并在接收到连接时生成一个 Socket 对象,用于与客户端进行双向数据通信。
    ServerSocket 基于 TCP(传输控制协议),确保数据传输的可靠性和顺序性。

客户端和服务端tcp协议的案例

java 复制代码
服务器端:创建一个 Socket,绑定到特定的 IP 地址和端口,并等待客户端连接。
客户端:创建 Socket,连接到服务器的 IP 地址和端口。
客户端和服务器通过输入输出流(InputStream 和 OutputStream)发送和接收数据。

客户端

java 复制代码
package test01;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class User {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Socket socket = null;
        try {
             // 创建 Socket 对象,连接到服务器的 IP 地址和端口
            socket = new Socket("localhost", 8080);
            //输入
            OutputStream out = socket.getOutputStream(); //输出流
            String a="你好,我要登录";
//            String a="我要登录账号,帮我查看一下";
            out.write(a.getBytes());
            //读取输入流
            InputStream in=socket.getInputStream();
            byte buffer[]=new byte[1024];
            in.read(buffer); // 读取数据
            String received = new String( buffer);
            System.out.println(received);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服务器端

java 复制代码
package test01;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Servers {
    public static void main(String[] args) {
        try {
            Scanner scanner = new Scanner(System.in);
             // 创建 ServerSocket 对象,监听端口 8080
            ServerSocket serverSocket=new ServerSocket(8080);
            System.out.println("Server is listening on port 8080");
            //等待客户端连接
            Socket socket=serverSocket.accept();
            //获得输入信息
            InputStream in = socket.getInputStream();
            byte buffer[]=new byte[1024];
            int bytesRead = in.read(buffer); // 读取数据
            String received = new String(buffer ,0, bytesRead);
            System.out.println("用户发送内容:" + received);
            //给客户端发送信息
            OutputStream out = socket.getOutputStream();

            String a="马上";
            out.write(a.getBytes());

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

2.DatagramPacket/DatagramSocket (UDP)

java 复制代码
DatagramPacket:封装要发送或接收的数据包。
DatagramSocket:发送和接收 DatagramPacket 的套接字,用于建立 UDP 通信。
一、DatagramPacket
java 复制代码
DatagramPacket 是 Java 中用来存储发送或接收的数据包。UDP 通信中,数据是以独立的数据报(Datagram)的形式发送和接收的,每个数据报都使用 DatagramPacket 来封装。
接收:
DatagramPacket(byte[] buf, int length)
接收数据时,指定一个缓冲区 buf 和数据的长度 length。
发送:
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
发送数据时,指定要发送的数据 buf、数据长度 length、目标地址 address 和端口号 port。
getData():返回数据报中的数据。
getLength():返回数据的实际长度。
getAddress():返回数据报的来源或目的地的 InetAddress 对象。
getPort():返回数据报的来源或目的地的端口号。
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("localhost"), 9876);
二、DatagramSocket
java 复制代码
是用于发送和接收 DatagramPacket 的套接字。它实现了无连接的通信协议(UDP),即不需要建立连接即可发送和接收数据。
创建一个 UDP 套接字并绑定到指定端口:
DatagramSocket(int port)
//常用方法
send(DatagramPacket p):发送数据包 p。
receive(DatagramPacket p):接收数据包 p。
close():关闭套接字。
// 发送端
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName("localhost");
String msg = "Hello, UDP!";
byte[] buffer = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 12345);
socket.send(packet);
socket.close();

UDP发送信息案例

客户端

java 复制代码
package test03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;

public class Customer {
    //客户
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        DatagramSocket socket=null;
        DatagramPacket packet=null;
        try {
         while (true){
             //发送的内容
             System.out.print("请输入");
             String news=scanner.next();
             byte[] buffer = news.getBytes();//转化为字节
             //字节数组  数组长度  IP地址 端口号
             packet = new DatagramPacket(
                     buffer,
                     buffer.length,
                     InetAddress.getByName("localhost"),
                     9876);
             //DatagramSocket 是用于发送和接收 DatagramPacket 的套接字。
             //创建发送对象
             socket = new DatagramSocket();
             socket.send(packet);
             System.out.println("发送内容:" + news);

             //接收信息
             byte[] buffer1 = new byte[1024];
             //创建一个空包去接收别人发送的信息
             packet= new DatagramPacket(buffer1, buffer1.length);
             socket.receive(packet);
             //读取内容,转化为字符串
             String received = new String(packet.getData(), 0, packet.getLength());
             System.out.println("客服答复: " + received);
         }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            socket.close();//关闭
        }

    }
}

服务器端

java 复制代码
package test03;
import java.net.*;
import java.util.Scanner;
public class customerService {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //接收方
        DatagramSocket socket=null;
        DatagramPacket packet=null;
        try {
            //接收信息
            socket = new DatagramSocket(9876);
           while (true){
               //放入数组
               byte[] buffer = new byte[256];
               //包接收
               packet = new DatagramPacket(buffer, buffer.length);
               socket.receive(packet);
               //读取内容,转化为字符串
               String received = new String(packet.getData(), 0, packet.getLength());
               System.out.println("客户发送内容:" + received);
               //发送信息
               System.out.print("请输入");
               String news=scanner.next();
               byte[] buffer2 = news.getBytes();//转化为字节
               //于从接收到的 DatagramPacket 中获取客户端的 IP 地址
               ///这个方法用于获取发送该数据包的客户端的 端口号
               SocketAddress socketAddress = packet.getSocketAddress();
               packet = new DatagramPacket(buffer2, buffer2.length, socketAddress);
               socket.send(packet);//发送
               System.out.println("客服发送内容:" + news);
           }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            socket.close();//关闭
        }


    }
}

3.InetAddress

java 复制代码
InetAddress 类表示 IP 地址,它负责表示一个 IP 地址(IPv4 或 IPv6),并提供方法来查询和操作 IP 地址信息。
常用方法:
getByName(String host):根据主机名或 IP 地址字符串返回一个 InetAddress 对象。
getLocalHost():返回本地主机的 InetAddress。
getHostAddress():返回主机的 IP 地址的字符串表示。
getHostName():返回主机名。
复制代码
相关推荐
明月看潮生几秒前
青少年编程与数学 02-003 Go语言网络编程 15课题、Go语言URL编程
开发语言·网络·青少年编程·golang·编程与数学
雷神乐乐4 分钟前
File.separator与File.separatorChar的区别
java·路径分隔符
小刘|9 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
南宫理的日知录11 分钟前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
逊嘘28 分钟前
【Java语言】抽象类与接口
java·开发语言·jvm
Half-up31 分钟前
C语言心型代码解析
c语言·开发语言
morris13135 分钟前
【SpringBoot】Xss的常见攻击方式与防御手段
java·spring boot·xss·csp
龙哥说跨境1 小时前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
Source.Liu1 小时前
【用Rust写CAD】第二章 第四节 函数
开发语言·rust
monkey_meng1 小时前
【Rust中的迭代器】
开发语言·后端·rust