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

【JavaEE】网络编程套接字

目录

  • 网络编程的基本概念
    • 发送端和接收端
    • 请求和响应
    • 客户端和服务器
  • Socket套接字
    • Socket套接字功能分类
    • UDP实现客户端和服务器网络通信
      • DatagramSocket
      • DatagramPacket
      • 服务器具体代码实现
      • 客户端具体代码实现
    • TCP实现客户端和服务器网络通信
      • ServerSocket
      • Socket
      • 服务器具体代码实现
        • 缓冲区问题
        • 一次连接中,socket未关闭
        • 单线程无法处理多个客户端问题
      • 客户端具体代码实现

网络编程的基本概念

  • 网络编程就是指的是可以在网络上传输数据的程序(进程), 那么如果需要用到网络传输数据。那么我们就要使用网络协议,IP,端口号等。开发应用程序,使其能够在不同的计算机之间进行通信和数据交换。
  • 当然,我们只要满⾜进程不同就⾏;所以即便是同⼀个主机,只要是不同进程,基于⽹络来传输数据,也属于⽹络编程。
  • 但是我们一定要明确,我们大部分场景下都是不同主机进程之间的网络通信。
  • 比如我们要使用我们自己的笔记本电脑在百度客户端上搜索关于美女的图片, 这个时候呢我们电脑就会对百度服务器发送一个获取美女图片的请求。 百度的服务器就会在服务器的硬盘资源中查找是否有关于美女的图片, 这个时候找到了, 就会把美女图片构造成一个响应数据包返回给百度客户端。这个时候客户端就会显示我们的美女图片。这里客户端就是进程A, 服务器就是进程B

进程A:通过编程来获取所欲网络资源
进程B: 通过编程来提供它人所需网络资源

发送端和接收端

  • 在一次网络通信中,数据的发送进程。 叫做发送端,发送端主机即⽹络通信中的源主机。
  • 接收端:数据的接收⽅进程,称为接收端。接收端主机即⽹络通信中的⽬的主机。
  • 和我们上面讲的例子类似, 我们的笔记本电脑使用百度的客户端来搜索美女图片, 这个搜索美女图片是一个数据请求,这个时候我们百度客户端程序就会发送给百度服务器。百度客户端进程叫做发送端。服务器会收到这个请求, 并且让一个进程去处理这个任务。这个进程就叫做接收端。 此时有发送端的笔记本电脑就是源主机, 有接收端的服务器就是目的主机
    在这里插入图片描述

请求和响应

  • 一般来说获取一个网络资源涉及到两次网络数据传输
  • 第一次就是客户端发送请求数据包
  • 第二次就是服务器发送响应数据包
  • 这个就类似我们在炒饭店点一个炒饭, 我们给老板说我们要一份蛋炒饭,这是我们客户的请求。这个时候过一会老板就说:小伙子,你的炒饭好了。老板就会把炒饭给我(客户端), 这里老板就是服务器返回响应数据包(炒饭)

客户端和服务器

  • 客户端就是如同我们上面例子中, 提需求(要一份炒饭)的客户。 而我们网络中的客户端通常就是一台主机,对服务重提出他的请求。让服务器服务他。
  • 服务器呢就如同我们上面例子中, 炒饭的老板, 为客户提供服务(为客户炒饭), 而我们网络中的服务器通常也是一台主机, 对客户端的请求进行处理。

Socket套接字

  • Socket套接字是网络编程中的一个概念,他是通过网络进行通信的一种方式。由操作系统提供的用于网络通信的技术,Socket 用于封装底层的协议细节和通信逻辑,使应用程序可以通过简单直观的API与网络进行交互。所以客观的角度讲基于Socket 套接字开发,就是网络编程。
  • 他是传输层提供给应用层的一组操作系统API, 我们程序员只需要把应用层构造好的数据包使用这个socket类中的API就能把数据包发送给传输层进行后续的传输
  • 简单的说Socket套接字就是网络通信的工具, 好比我和我的朋友要进行打电话进行通信, 就必须要是使用电话这个工具,Socket套接字在两台主机进行网络通信中也是充当通信工具的作用。

Socket套接字功能分类

  • 首先,如果我们要进行网络通信, 那么通信双方都要遵守标准的网络协议, 网络协议规定了通信双方的数据发送格式, 数据解析格式等等。常见的就是TCP/IP五层网络模型。
  • 在这里插入图片描述
  • 下层协议对上层协议提供服务
  • 网络编程实在应用层进行的, 这个时候我们就要让传输层给应用层提供服务, 在应用层构造好网络数据包后就要交给传输层后续处理。这个时候该怎么传输给网络层呢? 传输层就提供了Socket类的API让我们通过这个工具进行使用完成传输。

而Socket(套接字)主要争对传输层协议划分为如下三类:

  • 面向字节流套接字:基于传输层 TCP 协议
    面向字节流套接字是一种网络传输方式,基于传输层TCP协议实现。它将数据视为无结构的字节流,并在数据传输过程中保证数据的可靠性。

TCP协议的特点:

  1. 面向字节流读写:读写(IO)数据的时候就按照字节为基本单位进行读写
  2. 可靠传输: TCP 协议有超时重传的机制和确认应答机制,当发现连接没有问题,但数据没有成功传输的时候会重新发送数据。
  3. 全双工通信:同一个时间,允许双方同时通信。(比如双向车道, 允许同时两个反方向的行驶)
  4. 有连接:传输数据之前,通信双方先建立可靠连接,TCP协议保存了对端信息,不需要代码来实现保存
  5. 有接受缓冲区,也有发送缓冲区:在网络通信的时候,用于存储待发送或待接受数据,让我们传输效率提高, 不用频繁的网络IO传输。
  6. 传输数据的大小不受限制:字节流,流式传输,前提是有连接。5

UDP协议的特点:

  • 面向数据报读写:读写(IO)数据的时候按照数据报为基本单位读写
  • 不可靠传输:UDP协议没有超时重传和确认应答的机制,发出数据报后UDP协议就不会关心发送的过程是否正常和对端是否收到数据报
  • 全双工通信:同一个时间,允许双方同时通信。(比如双向车道, 允许同时两个反方向的行驶)
  • 无连接:传输数据并不需要建立连接, 也就是并没有互相保存对端的信息。通常需要代码来实现保存
  • 有接收缓冲区,⽆发送缓冲区
  • ⼤⼩受限:⼀次最多传输64k

UDP实现客户端和服务器网络通信

在这里插入图片描述
在这里插入图片描述

DatagramSocket

  • 这个API就是一个类似于把网卡抽象成文件的类型。我们知道网络传输通常用网卡作为输入和输出设备。这个时候我们用这个类的对象就可以做到对网卡进行读写操作。
    在这里插入图片描述
  • 这里只是他常用的两个构造方法。 其中第一个构造方法常用于客户端程序,客户端程序通常不需要绑定固定的端口。由操作系统自己分配。 因为我们使用固定的端口号是很容易在多个客户端同时访问一台服务器的场景下出现端口号竞争的, 程序员并不知道用户的电脑上这个除了客户端占用了这个端口是否还有其他程序占用这个端口,如果说客户端程序占用的端口和其他程序端口冲突了,那客户端就无法正常运行了。
  • 而第二个构造方法通常要绑定一个固定的端口号,这个构造方法通常用于服务器程序,因为我们一般的场景都是一台服务器给多个客户端提供服务。另一方面,如果服务器采用随机分配的端口。那么有可能第一次客户端能在A端口找到服务器。第二次客户端就不能在A端口找到服务器了,服务器搬到B端口了。这个时候客户端访问服务器就有点不稳定了。就好比我在观音桥开了一家卖重庆小面的店,今天在观音桥收获了一大批观音桥的忠实客户。结果第二天观音桥的老铁们又来到刚开始的地址发现我不见了,结果打听说我跑到四川成都去卖了,隔得太远了,他们也只好另外找一家店了,得嘞, 这批客户就损失了。所以我们的店最好是开在一个固定的位置, 让这些客户可以方便进行访问。我们的服务器也是如此
    在这里插入图片描述
  • receive通常用于接受客户端传输的数据报,如果客户端一直没有发送。程序就会进入阻塞等待

DatagramPacket

  • 在前面介绍UDP协议的时候,我们讲解了UDP协议的特性。其中一个特性就是UDP协议是面向数据报进行网络数据传输的。
  • 在网络编程中,我们通过socket对象来操作网卡进行网络数据的传输,这个时候我们采用的传输层协议是UDP。那么我们每次网卡传输的数据对象就应该是一个数据报。这个DatagramPacket类就是一个车数据报类,构造出来的对象就是一个数据报对象。
    在这里插入图片描述

在这里插入图片描述

服务器具体代码实现

在这里插入图片描述

  • 首先服务器我们需要通过网卡这个硬件把数据传输给客户端,这个时候我们就需要一个DatagramSocket对象来操作网卡。
  • 这个网卡对象绑定一个车固定的端口来表示服务器程序。方便客户端通过端口找到服务器程序。

在这里插入图片描述

  • 我们服务器启动的方法结构是一个死循环。因为我们并不知道客户端到底是在哪个时间会访问服务器,索性我们服务器程序就一直运行。也就是我们通常说的服务器一般7*24小时运行。

编写服务器程序的大致流程
1.读取并解析客户端的请求数据包
2.根据请求计算响应(最关键的步骤, 这里我们写的是回显服务器就很简单,只需要重述客户端数据)
3. 构造响应数据包,发给客户端。

在这里插入图片描述
在这里插入图片描述

  • 这个process计算响应就是一个简单的回显操作
  • udeEchoServer让服务器绑定固定端口

注意:UDP协议本身并没有具有连接的特性,也就是客户端和服务器之间并没有保存彼此的信息(如IP和端口号), 这个时候如果说我们服务器和客户端之间要进行通信。那么就要在代码中获取对方的IP和端口(如服务器从请求数据包中获取)。才能发送到指定的服务器/客户端。‘

  • 注意:我们的socket文件为啥不用关闭?这个是因为我们socket网卡文件的生命周期是跟随服务器程序的。只要当我们服务器程序关闭的时候,那么我们才不用一直从网卡文件里面读取客户端传输过来的数据。但是当服务器程序结束了。PCB(进程对象)就释放了,里面的文件描述符表也释放了,那么文件资源就被文件描述符表回收了,并不会造成文件资源泄露(没回收导致无效利用文件资源)。这个时候

客户端具体代码实现

在这里插入图片描述

  • 这里我们上面说了UDP协议本身并没有保存服务器/客户端的信息,如果我们客户端想要把数据包发给指定的服务器。那么就需要知道服务器的IP地址和端口号。所以我们这里采用两个成员变量来让存储服务器的IP和端口(这里让用户自己输入)
  • 如果我们想要把构造好的请求数据包发给服务器,那么就需要通过网卡来传输,这里用DatagramSocket对象来操作网卡。这里的客户端程序绑定的端口号是由操作系统随机分配的,保证了分配的端口是没被其他程序占用的。
    在这里插入图片描述

在这里插入图片描述

  • 用户输入服务器的IP和端口号,并且执行客户端程序

TCP实现客户端和服务器网络通信

ServerSocket

在这里插入图片描述

  • 这个API专用于服务器使用的网卡数据传输。

Socket

在这里插入图片描述

  • 这个API是服务器和客户端都可以使用的网卡,服务器通常是在用ServerSocket与客户端建立连接后, 网卡具体的读写操作是通过Socket这个类对象来完成的。

服务器具体代码实现

在这里插入图片描述

  • 通过ServerSocket来操作网卡,让服务器和客户端进行连接。这里也和UDP一样给服务器程序绑定一个固定端口号。

在这里插入图片描述

  • 这里我们通过serverSocket.accept()让服务器和客户端建立连接,并且创建出Socket类对象,负责网卡读写的操作。processConection方法处理连接后具体的操作

在这里插入图片描述

在这里插入图片描述

  • 由于是回显服务器那么只需要返回客户端发送的数据就行了。
缓冲区问题
  • 缓冲区实际上就是一块内存空间。那么为什么要有缓冲区呢?因为我们IO过程中,无论是操作硬盘还是操作网卡都是速度非常慢很低效的。这个时候我们如果传输字节流这样的数据,100个字节分100次写到网卡里面去。那么我们就要对网卡进行100次IO操作,而我们普通的网卡通常IO速度是100MB/s, 相比内存IO速度普遍60GB/s的设置相差甚远。那么我们如果说1个字节IO一次实在是太低效了,网卡IO速度又慢。不妨把100个字节全部一次传输过去。节省了IO时间。这个时候我们就需要一个暂时存储数据的地方,这个地方就叫缓冲区。
  • 就如同我们嗑瓜子是一样的,如果说垃圾桶离我2公里,我如果每嗑一个瓜子就去垃圾桶扔,来回跑4公里回来再嗑一个,再来回跑4公里。那么是不是我I(跑过去)O(跑回来), 只扔一个瓜子效率太低了。不如把瓜子全部嗑完放在一个纸包里面,一次把全部瓜子扔了。效率更高。
    在这里插入图片描述
  • 而在我们TCP服务器发送数据给网卡的时候,也不会直接发给网卡,而是放在一个缓冲区里面。等待这个缓冲区满了,再把缓冲区的数据刷新给网卡。这个时候问题就来了,我通常一次请求并不会把缓冲区装满。那这个时候我们就不把结果发给客户端而是把他放在缓冲区等待很多个客户端装满缓冲区再一起发送吗?这很不科学的,我们应该处理完了就马上把结果发送给客户端。
  • 所以我们要手动刷新缓冲区的数据到网卡中

在这里插入图片描述

  • 注意:UDP不用刷新缓冲区是在应用程序上面不用刷新,操作系统内核里面还是会自动刷新的。这里TCP是在应用程序上面就要求刷新。
一次连接中,socket未关闭

在这里插入图片描述

  • 这里每次连接都不关闭socket网卡文件,那么每次客户端连接上服务器都会创建一个socket网卡文件,客户端多了,未关闭的socket文件就闲着不用了(占着茅坑不lashit),资源泄露,就会耗尽文件描述符表的位置。
单线程无法处理多个客户端问题

在这里插入图片描述

  • 这个时候就是因为只有一个线程在执行段逻辑。线程1又要执行processConection()的逻辑,又要和其他客户端建立连接。可是如果说当前客户端不输入请求也不断开连接,就会无法让线程1和其他客户端建立连接。
  • 好比一个服务员服务客户1,客户1一直不点菜完事,在这里有的没的。客户2和客户3需要服务员提供服务,但是这家餐厅只有一个服务员正在服务客户1,就必须等这个服务员服务完了客户1才能和他们进行连接服务。
  • 问题看清了,根本原因就是一个线程(服务员)搞不过来。这个时候我们多搞几个线程(服务员)就行了。让一个线程专门和客户端建立连接。另外的线程专门处理processConection逻辑
    在这里插入图片描述
  • 这个newCachedThreadPool线程池会自动扩容线程来执行下面的processConection方法,线程1就专门负责和多个客户端建立连接。这样就解决了这个问题
  • 注意:和UDP对比,为什么UDP不用多线程,因为UDP服务器不用与客户端建立连接,在多客户端场景下,客户端1没发送请求,那么会在receive哪里阻塞。此时客户端2发送请求receive就会拿到客户端2的请求并返回结果。不会像TCP哪里一样还要去跳出processConection的循环去与客户端建立连接。
    在这里插入图片描述

客户端具体代码实现

在这里插入图片描述

  • 客户端的细节已经在服务器讲过
http://www.dtcms.com/a/396435.html

相关文章:

  • 网站优化基础tk域名
  • 怎么开网站企业网站推广排名
  • geo数据集合并 理解并准确解读PCA图中的批次效应对于数据分析至关重要
  • 沈阳网站建设费用公司网络组建方案
  • 类似qq空间的网站模板python做博客网站
  • 网站建设 深路互动域名备案接入商查询
  • 怎样做网站表白学校网站免费建设
  • 西安做网站哪里便宜福州定制网站建设
  • 南通网站建设服务做视频网站 投入
  • 站长工具seo综合查询排名如何做网站的主页
  • 有没有做旅游攻略的网站如何做好集团网站建设
  • 怎样讲卖灯的网站做的好处营销网站建设新闻
  • 怎样设置默认网站鞍山网站
  • 做任务的电脑网站网页设计与制作教程机械工业出版社
  • ICCV-2025 | 对话协作驱动具身导航!DialNav:远程向导指导下的多轮对话导航
  • 石家庄红酒公司 网站建设mysql优化 wordpress
  • 网站开发 网站建设仿豆瓣 wordpress
  • 电商网站建设 数商云成都网站开发外包
  • 博达站群网站建设教程营销论坛网站建设
  • 成都城乡建设网站商标注册查询方法
  • 搭建网络环境昆明百度seo
  • 医疗知识普及网站开发惠州高端网站建设
  • 网站制作说明书厦门网站建设 模板建站
  • 网站建设实习周记培训网站建设方案说明
  • 我做中医培训去哪个网站找学员海报设计制作平台
  • jquery 打开新网站医疗网站建设怎么样
  • 最火的网站开发语言游戏交易网站开发
  • qemu-img格式转换教程
  • 网站开发浏览器包抖音推广seo
  • 河南网站关键词优化代理随州网站制作价格