当前位置: 首页 > news >正文

【JavaEE】网络原理之初识(1.0)

目录

​编辑

局域网与广域网 

IP地址和端口号 

实现简单的服务器客户端交互

简单理解socket 

TCP和UDP的差别(初识)

socket面对udp 

DatagramSocket API

DatagramSocket 构造方法

DatagramSocket 方法:

DatagramPacket API 

DatagramPacket 构造方法:

DatagramPacket 方法:

实现回显服务器和客户端

网络协议 


局域网与广域网 

随着时代的发展,越来越需要计算机之间互相通信,共享软件和数据,即以多个计算机协同工作来完成业务,就有了网络互连。

网络互连:将多台计算机连接在一起,完成数据共享。

数据共享本质是网络数据传输,即计算机之间通过网络来传输数据,也称为网络通信。

根据网络互连的规模不同,可以划分为局域网广域网

 局域网是本地,局部组建的一种私有网络

局域网内的主机之间能方便的进行网络通信,又称为内网;局域网和局域网之间在没有连接的情况下,是无法通信的。

其能通过路由器去使几台电脑去连接在一块,但数量是有限的。
一般家用路由器,常见的是5 个网口:1WAN + 4LAN
要想让这几个电脑能够在同一个局域网中上网,就需要把他们连接到LAN 口,WAN 口是用来连上级的路由器的。
那么能不能让一个路由器连接的电脑更多呢?
有个叫交换机的东西: 可以扩展路由器的端口,我们把路由器的LAN口连在交换机上,交换机上有一定数量的LAN口从而可以连一定数量的电脑,这样就可以扩展电脑的数量。

除此之外还有上级路由器连多个下级路由器,从而更多电脑连接在一块。

那么如果我们在上述设备层层连接之下,就可以构成更复杂的网络结构了,把更多更多的局域网连接到一起,构成的网络更加庞大,可能已经覆盖了一个城市,一个国家,就叫广域网。

对于广域网和局域网的定义没有准确的数量要求。(我们感觉非常多的电脑(10w台这种)连接在一块就是可以称为广域网)

IP地址和端口号 

IP地址描述了一个设备,在网络上的地址,

生活中: 吉林省长春市东北师范大学光华xxx
而在计算机中: 使用一个 32 位, 4 字节数字, 表示地址

一般来说,我们会把 IP 地址给表示成 4 个 0-255 之间的十进制数字,并且使用 3个点进行分隔.点分十进制(192.168.2.100)

在网络通信中,IP地址用于标识主机网络地址,端口号可以标识主机中发送数据、接收数据的程序。简单说:端口号用于定位主机中的程序

类似发送快递时,不光需要指定收货地址(IP地址),还需要指定收货人(端口号)

格式为:
端口号是0~65535范围的数字(两个字节),在网络通信中,程序可以通过绑定一个端口号,来发送及接收网络数据

注意事项:

两个不同的程序,不能绑定同一个端口号,但一个进程可以绑定多个端口号

举个例子:mysql可以绑定一个端口号3306,也可以在绑定其他的端口号,但是其他程序不行绑定3306了。

特殊说明:               

1-1023 (0不用作端口号)这个范围的端口号,系统留作特殊用途,咱们写的程序不应该占用
知名端口号,这些留给一些比较常见的服务器程序进行使用的(都是系统必要的)
22 => ssh
80 => http
443 => https
23 => telnet 

实现简单的服务器客户端交互

简单理解socket 

 之前提过在网络编程中,应用层到运输层需要显式调用 API,而运输层到网络层以及后续层的通信通常是自动处理的,不需要开发者主动调用 API,反过来也是同理。

这里显示调用的API就是socket(套接字) ,只有调用了它,数据才能运输成功 

由于传输层提供了两个最核心的协议:UDP TCP。
因此,socket api 中也提供了两种风格来面对UDP和TCP。(传输层用哪种协议就用哪种风格去应对)

对于socket 不仅是个API,本质上是一种特殊的文件.Socket 就属于是把"网卡"这个设备,给抽象成了文件了往 socket 文件中写数据,就相当于通过网卡发送数据.从 socket 文件读数据,就相当于通过网卡接受数据 

TCP和UDP的差别(初识)

TCP的特点:

有连接
可靠传输
面向字节流
全双工

UDP的特点:

无连接
不可靠传输
面向数据报
全双工

连接:
此处说的"连接"不是物理意义的连接,而是抽象,虚拟的连接。
计算机中,这种 抽象 的连接是很常见的,此处的连接本质上就是建立连接的双方,各自保存对方的信息,两台计算机建立连接,就是双方彼此保存了对方的关键信息(ip和端口)
所以这也意味着如果协议是tcp的话,必须要先建立好连接才能传输信息,如果是udp,就不用建立连接就能传输消息。

可靠传输/ 不可靠传输:
网络上存在的"异常情况"是非常多的,无论使用什么样的软硬件的技术手段无法100%保证网络数据能够从A一定传输到。此处谈到的"可靠传输",尽可能的完成数据传输。虽然无法确保数据到达对方,至少可以知道,当前这个数据对方是不是收到了。
此处谈到的可靠传输,主要指的是发的数据到没到,发送方能够清楚的感知到。

面向字节流/面向数据报
面向字节流:此处谈到的字节流和文件中的字节流完全一致—— TCP(网络中传输数据的基本单位就是字节)
面向数据报:udp每次传输的基本单位是一个数据报(由一系列的字节构成的),它是特定的结构

全双工/半双工:

全双工通信允许数据同时在两个方向上传输。这意味着通信双方可以同时发送和接收数据,而不会互相干扰。

半双工通信允许数据在两个方向上传输,但不能同时进行。通信双方只能交替地发送和接收数据。

socket面对udp 

udp时的socket相较于tcp,要相对简单,我们先讲这个

DatagramSocket API

DatagramSocket 是UDP时的Socket,用于发送和接收UDP数据报。 

DatagramSocket 构造方法

DatagramSocket 方法:

DatagramPacket API 

 DatagramPacket是UDP Socket发送和接收的数据报(UDP面向数据报,每次发送接收数据的基本单位,就是一个UDP数据报)

DatagramPacket 构造方法:

由于udp是没建立连接的,所以每次发送都要标明要发送的对方ip和端口。(如果建立了连接就不需要发送ip和端口)

DatagramPacket 方法:

构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创建。

实现回显服务器和客户端

注:这里编写的客户端服务器是一个简单 UDP 版本的服务器,称之为:回显服务器。
一个普通的服务器: 收到请求,根据请求计算响应(业务逻辑),返回响应。
回显服务器: 省略了普通服务器的 “根据请求计算响应”(这里的响应一般非常复杂),这里只是为了演示 socket api 的用法。

 这里有一个重点要说下:
对于一个服务器来讲,我们需要让其绑定一个明确的端口号,因为在服务器在网络传输中处于一个被动的状态,没有一个明确的端口号,客户端就无法寻找到请求的服务器。
而对于一个客户端来说,我们可以让其随机分配一个端口号给他,不要指定,因为客户端是客户使用,不像我们程序员知道怎么分配端口,客户不清楚怎么分配端口,万一客户指定的端口被别人占用就会报错,它还不知道怎么修改,所以采用随机分配。(随机分配的都是没被占用的端口号)
以后的服务器客户端 端口号都遵循这规定

服务器端的逻辑如下:
1. 创建套接字:创建一个 DatagramSocket 对象,并绑定到指定的端口(10003),用于接收和发送数据报。
2. 接收数据报:在 while (true) 循环中,创建一个 DatagramPacket 对象,用于接收客户端发送的数据报。调用 datagramSocket.receive(datagramPacket) 方法等待并接收数据报。
3. 处理数据:将接收到的数据报中的字节数组转换为字符串,然后调用 process 方法处理该字符串。在这个例子中,process 方法只是简单地返回传入的字符串本身。
4. 发送响应:将处理后的字符串转换为字节数组,并创建一个新的 DatagramPacket 对象,包含要发送的数据、目标地址和端口(即客户端的地址和端口)。使用 datagramSocket.send(datagramPacket1) 方法将响应数据报发送回客户端。
5. 循环处理:上述步骤在 while (true) 循环中不断重复,服务器持续等待接收新的数据报并响应,直到程序被手动终止。

客户端设计逻辑:

创建套接字:创建一个 DatagramSocket 对象,用于发送和接收数据报。这个套接字没有绑定到特定的端口,因此会使用一个临时端口。

读取用户输入:使用 Scanner 从控制台读取用户输入的字符串。

发送数据报:

将用户输入的字符串转换为字节数组。

创建一个 DatagramPacket 对象,包含要发送的数据、目标地址和端口。

使用 DatagramSocket 发送数据报。

接收响应:

创建一个 DatagramPacket 对象,用于接收服务器的响应。

使用 DatagramSocket 接收数据报。

将接收到的字节数组转换为字符串并打印到控制台。

循环处理:上述步骤在 while (true) 循环中不断重复,直到程序被手动终止。

public class Serve {public static void main(String[] args) throws IOException,InterruptedException {System.out.println("服务器上线");DatagramSocket datagramSocket=new DatagramSocket(10003);while(true){DatagramPacket datagramPacket=new DatagramPacket(new byte[4096],4096);datagramSocket.receive(datagramPacket);String string=new String(datagramPacket.getData(),0,datagramPacket.getLength());byte[] bytes1=process(string.getBytes());DatagramPacket datagramPacket1 = new DatagramPacket(bytes1,bytes1.length,new InetSocketAddress(datagramPacket.getAddress(),datagramPacket.getPort()));datagramSocket.send(datagramPacket1);}}public static String process(String string){return  string;}
}
public class Client {public static void main(String[] args) throws IOException {System.out.println("客户端启动");Scanner scanner=new Scanner(System.in);DatagramSocket datagramSocket=new DatagramSocket();while(true){String string=scanner.next();byte[] bytes=string.getBytes();DatagramPacket datagramPacket1 = new DatagramPacket(bytes,bytes.length,new InetSocketAddress("192.168.50.173",10003));datagramSocket.send(datagramPacket1);DatagramPacket datagramPacket=new DatagramPacket(new byte[4096],4096);datagramSocket.receive(datagramPacket);String string1=new String(datagramPacket.getData(),0,datagramPacket.getLength());System.out.println(string1);}}
}

对于这里我们要特殊说几个点:

1.对于字节数组内部存储数据报并不可能是全部都占用了,肯定有空闲空间,所以在将该字节数组变为字符串时我们肯定要把空闲空间给划掉,这时候就用datagrampacket.getlength ()得到有效长度,从而就可以忽略掉,否则会引发bug

2.仔细观察代码,发现该服务器可以同时支持多个客户端

这里有个疑问,一段代码为什么会能实现多个窗口呢?一般不是只能一段代码实现一个?这玩意我们是可以修改的

通过这样修改,我们就能一段代码生成多个实例对象,多个窗口(客户端)。

3.对于该DatagramSocket虽然是文件,但是并不需要close,因为Datagramsocket是全程跟随该进程的,当进程结束时,我们才不会用DatagramSocket,进程只要还在运行,它依然还会用。该进程结束时文件描述表自然就销毁了,根本不用再添一个close。

网络协议 

网络协议是网路通信中的规则和标准,它用于定义网络通信中数据的传输方式、数据包的结构、数据包中的信息内容以及通信双方的行为等。只有统一规范好了网络协议(规则),电脑们之间才能通信成功。

本节课的内容就到这里了,剩下的等我下节再讲

相关文章:

  • PH热榜 | 2025-04-30
  • AI与无人零售:如何通过智能化技术提升消费者体验和运营效率?
  • 写劳动节前的 跨系统 文件传输
  • ArrayList的特点及应用场景
  • 【计算机视觉】图像分割:Segment Anything (SAM):通用图像分割的范式革命
  • 【Linux】Linux 系统中,定时任务(计划任务)
  • 代码随想录算法训练营第三十一天
  • 一种导弹追踪算法的MATLAB仿真实现
  • Windows 系统中安装 flash - attn
  • Dify添加ollama模型失败:NewConnectionError: Failed to establish a new connection
  • [Android 15] 在GlobalActionsDialog 中新增项目
  • 国内 AI 发展路线分析
  • Arduino IDE中更新esp32 3.2.0版本的办法
  • 大力探索“AI·Life爱生活”项目峰会暨战略投资签约仪式成功举办
  • ‌阿里云dns服务器不可用怎么办?dns可以随便改吗?
  • 编译原理实验二:构建TINY语言的词法分析器
  • 第15篇:Linux设备驱动程序入门<二>
  • MicroPython 开发ESP32应用教程 之 ADC及应用实例:电池电量检测并显示
  • js闭包概念和使用
  • 从实列中学习linux shell5: 利用shell 脚本 检测硬盘空间容量,当使用量达到80%的时候 发送邮件
  • 新华时评:需要“重新平衡”的是美国心态
  • 奔驰一季度利润降四成,受美国加征关税影响放弃全年盈利展望
  • “铁血防守”制造8年最快丢球,恐惧中的阿森纳什么也做不了
  • 癌症来临前,可能伪装成这几种常见病,千万别大意
  • 文天祥与“不直人间一唾轻”的元将唆都
  • 纪念|海上金石学的兴盛与王昶《金石萃编》