Socket通信讲解及C/S结构实现UDP协议通信

news2024/10/2 8:38:54

Sokcet


一. Socket套接字

1.1 什么是套接字


所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制,是支持TCP/IP协议的路通信的基本操作单元

1.2 套接字主要类型


TCP流套接字

流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP协议。即传输层TCP通信满足如下条件:

  • 有连接可靠传输
  • 面向字节流,即可以利用IO流分开进行多次收发
  • 有接受的缓冲区和传输缓冲区,没有传输大小限制

UDP数据报套接字

数据报套接字提供一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。即传输层UDP通信满足如下条件:

  • 无连接不可靠传输
  • 面向数据报,即发送的内容必须一次性收发
  • 有接受的缓冲区,但没有发送的缓冲区,一次性最多传输64k大小

原始套接字

原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送的数据必须使用原始套接。

二. UDP常见API

2.1 DatagramSocket

DatagramSocket 用来构造传输UDP协议的类,表格介绍如何构造类对象

构造方法含义
DatagramSocket(int port)创建一个UDP数据报套接字Socket,绑定到指定的端口

表格介绍DatagramSocket 常用的传输和接受数据包方法

方法含义
void receive(DatagramPacket p)套接字接收数据报
void send(DatagramPacket p)套接字发送数据报包
void close()关闭套接字

2.2 DatagramPacket


DatagramPacket 用来构造传输数据包的类,表格介绍如何构造类对象

构造方法含义
DatagramPacket(byte[] buffer, int length)构造数据包接受数据,parm1:接受的内容,parm2:指定接受的长度
DatagramPacket(byte[] buffer, int offset, int length,SocketAddress address)构造数据包发送数据,parm1:发送内容,parm2:从字符组下标哪里开始发送,parm3:发送的长度、parm4:封装目的IP和端口对象

表格介绍DatagramPacket 常用的方法

方法含义
InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int getPort()从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号
byte[] getData()获取数据报中的数据

2.3 SocketAddress


在上述DatagramPacket对象发送数据包时,需要构造SocketAddress 来封装IP和端口,我们常使用SocketAddress 的子类InetSocketAddress来构建对象

构造方法含义
InetSocketAddress(InetAddress address, int port)创建一个Socket地址,包含IP地址和端口号

三. C/S结构测试


3.1 TCP通信


TCP网络协议通信可查看这篇文章:
利用TCP网络编程实现客户端和服务端简单交互

3.2 UDP通信


下面讲解如何利用Socket实现C/S结构的UDP协议通信,如下图为传输过程
在这里插入图片描述

服务端Server

//构建UDP协议的服务端
public class UDPServer {
    //构建套接字
    DatagramSocket socket;

    //构建协议对象(参数表示服务器端口号)
    public UDPServer(int serverPort) throws SocketException {
        socket = new DatagramSocket(serverPort);
    }

    //开启服务器进行监听
    public void startListening() throws IOException {
        System.out.println("===============服务器开启监听===================");
        Scanner scanner = new Scanner(System.in);//用来回复
        while (true){
            //1.构建数据包用来接受数据
            DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
            //2.等待接受数据(没有返回值,但是已经接收到了数据)
            socket.receive(receivePacket);

            //3.将接受的数据取出
            String receiveData = new String(receivePacket.getData(),0,receivePacket.getLength());
            //如果客户端发送来ex或exit则退出
            if ("ex".equals(receiveData) || "exit".equals(receiveData)){
                System.out.println("===============服务器退出===================");
                break;
            }

            //4.根据请求进行回复
            System.out.println("收到消息:{"+receiveData+"}");
            System.out.println("请输入想要回复的信息:");
            String answer = scanner.nextLine();
            byte[] answerBytes = answer.getBytes();

            //5.将回复封装为数据包发送回客户端
            //注意:这里是根据接受的数据包来获取发送方的ip和端口
            DatagramPacket answerPacket = new DatagramPacket(answerBytes, 0, answerBytes.length, receivePacket.getSocketAddress());
            socket.send(answerPacket);

        }
    }
    

    public static void main(String[] args) throws IOException {
        UDPServer udpServer = new UDPServer(8899);
        udpServer.startListening();
    }

}

客户端Client

//构建UDP协议的客户端
public class UDPClient {
    //服务器端口号
    int serverPort;
    //服务器ip
    String serverIp;
    //构建套接字
    DatagramSocket socket;

    //构建协议对象(参数表示服务器端口号和服务器ip地址)
    public UDPClient(int serverPort, String serverIp) throws SocketException {
        this.serverIp = serverIp;
        this.serverPort = serverPort;
        this.socket = new DatagramSocket();
    }


    public void startSend() throws IOException {
        System.out.println("===============客户端开启接受===================");
        //1.获取输入
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("请输入想要发送的信息:");
            String request = scanner.nextLine();
            byte[] requestBytes = request.getBytes();

            //2.构建数据包
            //InetAddress.getByName()表示根据服务器主机名称解析ip地址
            DatagramPacket requestPacket = new DatagramPacket(requestBytes, 0, requestBytes.length, InetAddress.getByName(serverIp), serverPort);

            //3.发送数据包
            socket.send(requestPacket);
            //设定退出
            if ("ex".equals(request) || "exit".equals(request)){
                System.out.println("===============客户端退出===================");
                break;
            }

            //4.构建数据包用来获取响应
            DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
            socket.receive(receivePacket);

            //5.将获取的数据取出
            String receiveData = new String(receivePacket.getData(),0,receivePacket.getLength());
            System.out.println("收到消息:{"+receiveData+"}");

        }
    }


    public static void main(String[] args) throws IOException {
        UDPClient udpClient = new UDPClient(8899, "192.168.31.104");
        udpClient.startSend();
    }
}

服务器端运行在192.168.31.104上,利用如下代码开启监听:

java -cp NetworkSocket-1.0-SNAPSHOT.jar com.nuaa.mySocket.server.UDPServer               

客户端运行在本地,通信对话如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yKrsakMb-1685345822236)(C:\Users\29973\AppData\Roaming\Typora\typora-user-images\image-20230529153224095.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c4U7ys98-1685345822237)(C:\Users\29973\AppData\Roaming\Typora\typora-user-images\image-20230529153244166.png)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/584919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java:map集合的应用,含代码以及输出样例

目录 1.Map集合 创建 基本的map使用方法 添加数据&#xff0c;打印数据 获取长度&#xff0c;删除元素&#xff0c;判断元素是否存在 map中常用的函数 1.Map集合 创建 Map<String,String> map new HashMap<>(); 基本的map使用方法 添加数据&#xff0c;打…

五.Glide

文章目录 前言1.with方法1.1 如何监听Glide的生命周期1.2 生命周期作用域Application、Activity、Fragment1.3 生命周期的绑定1.4 生命周期的监听1.5生命周期的回调 2.load方法3.into方法3.1 into方法的源码中流程走向3.2 Glide活动缓存的由来 4.Glide缓存机制4.1 资源封装4.2 …

(一)、Arcgis Server等一系列软件安装前准备

文章目录 &#xff08;一&#xff09;、win10修改机器名&#xff08;1&#xff09;、打开&#xff1a;设置->重命名这台电脑&#xff08;2&#xff09;、在弹出的系统属性框点击 "更改按钮"&#xff08;3&#xff09;、在弹出的计算机名/域更改点击 "其他&qu…

赋能数字化!企企通荣获“中国企业服务产业最佳投资案例TOP10”

近日&#xff0c;国内投资行业权威机构「投中信息」发布的投中2022年度中国创业投资机构暨私募股权投资机构系列榜单&#xff08;“投中2022年度榜单”&#xff09;隆重揭晓&#xff0c;企企通作为国内一站式采购数字化管理平台领军者&#xff0c;成功入选“2022年度企业服务产…

体积小、无广告、超实用的5款小工具

大家好&#xff0c;我又来啦&#xff0c;今天给大家带来的5款软件&#xff0c;共同特点都是体积小、无广告、超实用&#xff0c;大家观看完可以自行搜索下载哦。 1.动态桌面——WinDynamicDesktop WinDynamicDesktop是一款用于根据时间和地点自动更换桌面壁纸的工具。它可以让…

从零搭建微服务-认证中心(四)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff1a;https://gitee.com/csps/mingyue 文档地址&#xff1a;https://gitee.com/csps/mingyue/wikis 搭建前端框架 感谢开源项目【vue-next-adm…

TDengine 启动 taosAdapter,提供基于6041端口的RESTful 接口,建立REST 连接

一、前文 TDengine 入门教程——导读 二、开发指南 TDengine 完整的软件包包括&#xff1a; 服务端&#xff08;taosd&#xff09;&#xff1b;命令行程序 (CLI&#xff0c;taos) 和一些工具软件&#xff1b;用于与第三方系统对接并提供 RESTful 接口的 taosAdapter&#xff1…

evpn route抓包

EVPN路由的种类比较多&#xff0c;每个类型抓一个包在此留存&#xff0c;以备不时之需。 与君共勉。 每种EVPN路由的具体作用及工作方式可以参见VXLAN专栏中其它文章。 Type1 当各网关设备之间的BGP EVPN邻居关系建立成功后&#xff0c;网关设备之间会传递以太自动发现路由。…

Pod生命周期

Pod生命周期 Pod创建过程运行初始化容器过程运行主容器过程 容器启动后钩子&#xff0c;容器终止前钩子容器存活性&#xff0c;就绪性探测 Pod终止过程 在整个Pod生命周期&#xff0c;会出现5中状态&#xff1a; 取值描述Pending&#xff08;悬决&#xff09;Pod 已被 Kubern…

聚数成峰,共赢未来,openGauss Developer Day 2023在京举行

[2023年5月26日 中国 北京]5月25日-26日&#xff0c;以“聚数成峰&#xff0c;共赢未来”为主题的 openGauss Developer Day 2023&#xff08;openGauss开发者大会2023&#xff09;在北京举办。本届大会在中国计算机学会、国家工业信息安全发展研究中心指导下&#xff0c;由ope…

Springboot +spring security,认证方式---Form表单认证的实现(一)

一.简介 这篇文章来学习下security的认证方式其中的Form表单认证 二.Spring Security的认证方式 2.1什么是认证 认证: 就是用来判断系统中是否存在某用户&#xff0c;并判断该用户的身份是否合法的过程&#xff0c;解决的其实是用户登录的问题。认证的存在&#xff0c;是为…

数据挖掘实战(以kaggle为例)

第一课 主要分为以下内容进行讲述 机器学习工业应用领域 机器学习常用算法 机器学习常用工具 解决问题流程 数据的处理比模型更为重要 老师的博客&#xff0c;内容很详细 数据预处理 有时候可以一个feature一个feature去做 特征工程 模型选择 模型状态评估 模型融合 B…

消息通知配置-shorp

消息通知配置 注意事项&#xff1a; 消息均采用异步发送&#xff0c;请提前配置好队列&#xff0c;点这里配置队列配置完之后请别忘记在列表切换消息为启用状态 模板消息配置方式 (以订单发货通知为例) 准备工作 查看后台 消息通知 -》 消息配置 -》 订单发货通知编辑 微信公…

牛客网基础语法1~10题

牛客网基础语法1~10题 前言&#xff1a;今天是咱们第一期刷牛客网上的题目。 目标&#xff1a;掌握基础编程&#xff0c;打牢基础知识&#xff0c;有一定的编程思想 鸡汤&#xff1a;读不在三更五鼓&#xff0c;功只怕一曝十寒。先干为敬&#xff0c;大家随意。 第一题 #includ…

内网环境制作nacos镜像

1. 拉取用于构建的镜像 git clone https://github.com/nacos-group/nacos-docker.git 拉去下来是这样的 下载nacos压缩包 https://github.com/alibaba/nacos/tags 以2.2.2版本为例 将下载的压缩包&#xff0c;放到build文件夹 3. 修改Dockerfile文件 4.将build下的文件上…

复杂的网络

文章目录 1 查看windows的网络信息2 桥接模式和NAT模式3 连接开发板和虚拟机4. 网络分层、TCP、IO多路复用5. 家里的网络是怎么连接的 1 查看windows的网络信息 打开设置-网络查看 也可以直接cmd ipconfig 这次的网络连接&#xff08;我连接的手机热点&#xff09;是通过Inte…

由于找不到msvcr110.dll 无法继续执行怎么解决(最新解决方法分享)

MSVCR110.dll是Windows操作系统中的一个重要文件&#xff0c;一旦它出现丢失问题&#xff0c;会导致影响计算机整体的问题。这个跟MSVCP110.dll类似的误报&#xff0c;通常是由于安装编程工具或 部分无法正确安装所导致的问题。在这篇文章中&#xff0c;我们将一些解决此问题的…

Vulkan Tutorial 6 统一缓冲区

目录 20 layout and buffer 顶点着色器 描述符集布局 21 统一缓冲区 更新统一数据 22 Descriptor pool and sets 描述符池 描述符集 使用描述符集 对齐要求 20 layout and buffer 我们现在可以将任意属性传递给每个顶点的顶点着色器&#xff0c;模型-视图-投影矩阵将…

【干货分享】一篇文章帮你搞定前端高频面试题

前言 如今前端技术日新月异。对于前端开发人员来说&#xff0c;不仅需要掌握最新的前沿技术&#xff0c;还需要保持对基础知识的熟练掌握。而面试则是进入优秀企业的必经之路。在面试中&#xff0c;高频面试题的掌握是获得成功的关键。本文将为大家总结前端高频面试题及其答案&…

网络爬虫是什么

网络爬虫又称网络蜘蛛、网络机器人&#xff0c;它是一种按照一定的规则自动浏览、检索网页信息的程序或者脚本。网络爬虫能够自动请求网页&#xff0c;并将所需要的数据抓取下来。通过对抓取的数据进行处理&#xff0c;从而提取出有价值的信息。 认识爬虫 我们所熟悉的一系列…