【JAVAEE】网络编程的简单介绍及其实现

news2024/12/26 23:09:17

目录

1.什么是网络编程

网络编程中的基本概念

常见的客户端服务端模型

2.Socket套接字

Socket套接字分类

举例对比TCP和UDP

3.UDP数据报套接字编程

DatagramSocket API

DatagramPacket API

InetSocketAddress API

4.实现一个简单的UDP回显服务器与客户端

服务端与客户端的执行关系

代码



1.什么是网络编程

网络编程,指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。

注意:也可以是同一个主机的不同进程

网络编程中的基本概念

发送端和接收端

在一次网络数据传输时:
发送端 :数据的 发送方进程 ,称为发送端。发送端主机即网络通信中的源主机。
接收端 :数据的 接收方进程 ,称为接收端。接收端主机即网络通信中的目的主机。
收发端 :发送端和接收端两端,也简称为收发端。
注意:发送端和接收端只是相对的,只是一次网络数据传输产生数据流向后的概念。

请求和响应

一般来说,获取一个网络资源,涉及到两次网络数据传输:
  • 第一次:请求数据的发送
  • 第二次:响应数据的发送。
好比在快餐店点一份炒饭:
先要发起请求:点一份炒饭,再有快餐店提供的对应响应:提供一份炒饭

客户端和服务端

服务端 :在常见的网络数据传输场景下,把 提供服务 的一方进程,称为服务端,可以提供对外服务。
客户端 获取服务 的一方进程,称为客户端。

常见的客户端服务端模型

最常见的场景,客户端是指给用户使用的程序,服务端是提供用户服务的程序:
1. 客户端先发送请求到服务端
2. 服务端根据请求数据,执行相应的业务处理
3. 服务端返回响应:发送业务处理结果
4. 客户端根据响应数据,展示处理结果(展示获取的资源,或提示保存资源的处理结果)

2.Socket套接字

概念:Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。

Socket套接字分类

Socket套接字主要针对传输层协议分为如下三类:

流套接字:使用传输层TCP协议

TCP,即Transmission Control Protocol(传输控制协议),传输层协议

TCP特点:

  • 有连接
  • 可靠传输
  • 面向字节流
  • 有接收缓冲区,也有发送缓冲区
  • 大小不限

传输数据时基于IO流,没有边界,可以多次发送,多次接收。

数据报套接字:使用传输层UDP协议

UDP,即User Datagram Protocol(用户数据报协议),传输层协议。

补充:数据报是通过网络传输的数据的基本单元,包含一个报头(header)和数据本身,其中报头描述了数据的目的地以及和其它数据之间的关系。

UDP特点:

  • 无连接
  • 不可靠传输
  • 面向数据报
  • 有接收缓冲区,有发送缓冲区
  • 大小受限,一次最多传输64K

传输数据时一个整体的传输,不能分开发送。

原始套接字:原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据。

举例对比TCP和UDP

1.有无连接

TCP相当于打电话(接听放必须要接通电话双方才可以通信)

UDP相当于发短信(对方有没有开机都不重要)

2.可靠传输

打电话时必须要经过拨号,接听后才可以童话,发短信发出去就不管了。如果数据包在传输的过程中丢了,TCP会有重传机制,UDP丢了就是丢了。

3.面向字节流:打电话说一个字对方就可以听到一个字

面向数据报:发短信法一条的信息,对方收到才可以阅读

4.有接收缓冲区,也有发送缓冲区:可以打电话也可以接电话,可以发短信也可以收短信

5.大小不限:电话打完了说好了我挂了啊,时间不受限,短信的大小有限制(有字数限制)

3.UDP数据报套接字编程

DatagramSocket API

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

DatagramSocket构造方法:

方法签名
方法说明
DatagramSocket()
创建一个 UDP 数据报套接字的 Socket ,绑定到本机任意一个随机端口(一般用于客户端
DatagramSocket(int
port)
创建一个 UDP 数据报套接字的 Socket ,绑定到本机指定的端口(一般用于服务端

DatagramSocket方法:

方法签名
方法说明
void receive( DatagramPacket p)
从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
void send( DatagramPacket
p)
从此套接字发送数据报包(不会阻塞等待,直接发送)
void close()
关闭此数据报套接字

DatagramPacket API

DatagramPacket是UDP Socket发送和接收的数据报。

DatagramPacket构造方法:

方法签名
DatagramPacket(byte[]buf, int length)
构造一个DatagramPacket 用来 接收 数据报,接收的数据保存在 字节数组(第一个参数 buf )中,接收指定长度(第二个参数length)
DatagramPacket(byte[]
buf, int offset, int length,
SocketAddress adress)
构造一个DatagramPacket 以用来 发送 数据报,发送的数据为字节 数组(第一个参数 buf )中,从 0 到指定长度(第二个参数
length )。 address 指定目的主机的 IP 和端口号

DatagramPacket方法:

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

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

InetSocketAddress API

InetSocketAddress API(SocketAddress的子类)构造方法:

方法签名
方法说明
InetSocketAddress(InetAddress addr, int port)
创建一个 Socket 地址,包含 IP 地址和端口号

4.实现一个简单的UDP回显服务器与客户端

回显:客户端发什么服务器就返回什么。

服务端与客户端的执行关系

代码

服务器端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.StandardCharsets;


public class UDPEchoServer {
    // 定义一个用于服务器端的DatagramSocket
    private DatagramSocket server;

    /**
     * 构造方法,完成服务器的初始化
     * @param port 端口号
     */
    public UDPEchoServer (int port) throws Exception {
        if (port > 65535 || port < 1024) {
            throw new Exception("端口号必须在1024 ~ 65535之间");
        }
        // 初始化服务器端的UDP服务
        this.server = new DatagramSocket(port);
    }

    /**
     * 对外提供服务
     */
    public void start () throws IOException {
        System.out.println("服务器已启动....");
        // 循环接收用户的请求
        while (true) {
            // 1. 创建一个用于接收请求数据的DatagramPacket
            DatagramPacket requestPacket = new DatagramPacket(new byte[1024], 1024);
            // 2. 接收请求, 把真实的内容填充到requestPacket
            server.receive(requestPacket);
            // 3. 从requestPacket获取数据
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength(), "UTF-8");
            // 4. 根据请求获取响应
            String response = processor (request);
            // 5. 把响应封装到DatagramPacket
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(StandardCharsets.UTF_8),
                    response.getBytes().length, requestPacket.getSocketAddress());
            // 6. 发送数据
            server.send(responsePacket);
            // 7. 打印日志
            System.out.printf("[%s:%d] request: %s, response: %s.\n", requestPacket.getAddress().toString(),
                    requestPacket.getPort(), request, response);
        }

    }

    public String processor(String request) {
        return request;
    }

    public static void main(String[] args) throws Exception {
        // 初始化服务器
        UDPEchoServer server = new UDPEchoServer(9999);
        // 启动服务
        server.start();
    }

}

客户端

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;


public class UDPEchoClient {
    // 定义一个用于客户端的DatagramSocket
    private DatagramSocket client;
    // 定义服务器的IP地址
    private String serverIp;
    // 定义服务器的端口号
    private int port;
    private SocketAddress address;

    /**
     * 构造方法,指定服务器的Ip地址和端口号
     *
     * @param serverIp 服务器IP
     * @param port 端口号
     */
    public UDPEchoClient (String serverIp, int port) throws SocketException {
        this.client = new DatagramSocket();
        this.serverIp = serverIp;
        this.port = port;
        this.address = new InetSocketAddress(serverIp, port);
    }

    public void start () throws IOException {
        System.out.println("客户端已启动.");
        // 循环接收用户的输入
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("->");
            // 接收用户输入
            String request = scanner.next();
            // 1. 把请求内容包装成DatagramPacket
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(StandardCharsets.UTF_8),
                    request.getBytes().length, address);
            // 2. 发送数据
            client.send(requestPacket);
            // 3. 接收响应
            DatagramPacket responsePacket = new DatagramPacket(new byte[1024], 1024);
            // 4. 在receive方法中填充响应数据
            client.receive(responsePacket);
            // 5. 解析响应数据
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength(), "UTF-8");
            // 6. 打印日志
            System.out.printf("request: %s, response: %s.\n", request, response);
        }
    }

    public static void main(String[] args) throws IOException {
        UDPEchoClient client = new UDPEchoClient("127.0.0.1", 9999);
        // 启动服务
        client.start();
    }

}

运行结果

 

 

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

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

相关文章

当前最新免费使用GPT-4方法汇总

目录 前言 温馨提示 Ora AI 使用方式 使用测试 Forefont chat 使用方式 使用测试 Perplexity AI 使用方式 使用测试 Poe 总结 前言 目前GPT-4的收费对于大多数人而言都还是不便宜&#xff0c;且付费方式复杂&#xff0c;使用上还有每3小时25个问题的限制&#xff…

Aspose.OCR For NET 23.5 Crack

使用几行代码将光学字符识别 (OCR) 添加到您的 .NET 应用程序。 适用于 .NET 的 Aspose.OCRAspose.OCR 文档 Aspose.OCR for .NET 是一个功能强大但易于使用且具有成本效益的光学字符识别 API。有了它&#xff0c;您可以用不到 5 行代码将 OCR 功能添加到您的 .NET 应用程序…

【Linux】初识优雅的Linux编辑器——Vim

❤️前言 大家好&#xff01;今天给大家带来的博客内容是关于Linux操作系统下的一款多模式文本编辑器Vim。本文将和大家一起来了解Vim编辑器的一些基础知识。 正文 Vim是一个多模式的文本编辑器(一共有十二种模式)&#xff0c;其中我们当我们初学Vim时主要了解如下三种工作模式…

Linux——多线程(线程概念|进程与线程|线程控制)

目录 地址空间和页表 如何看待地址空间和页表 虚拟地址如何转化到物理地址的 线程与进程的关系 什么叫进程&#xff1f; 什么叫线程&#xff1f; 如何看待我们之前学习进程时&#xff0c;对应的进程概念呢&#xff1f;和今天的冲突吗&#xff1f; windows线程与linux线…

Leetcode665. 非递减数列

Every day a Leetcode 题目来源&#xff1a;665. 非递减数列 解法1&#xff1a;贪心 本题是要维持一个非递减的数列&#xff0c;所以遇到递减的情况时&#xff08;nums[i] > nums[i 1]&#xff09;&#xff0c;要么将前面的元素缩小&#xff0c;要么将后面的元素放大。 …

K8s in Action 阅读笔记——【2】First steps with Docker and Kubernetes

K8s in Action 阅读笔记——【2】First steps with Docker and Kubernetes 2.1 Creating, running, and sharing a container image 2.1.1 Installing Docker and running a Hello World container 在电脑上安装好Docker环境后&#xff0c;执行如下命令&#xff0c; $ dock…

真会玩:莫言用ChatGPT为余华写了一篇获奖词

5月16日&#xff0c;《收获》杂志65周年庆典暨新书发布活动在上海舞蹈中心举行。 典礼现场&#xff0c;余华凭借《文城》获得收获文学榜2021年长篇小说榜榜首。 作为老友&#xff0c;莫言在颁奖时故意卖了个关子&#xff1a;“这次获奖的是一个了不起的人物&#xff0c;当然了&…

OMA通道-2

1 简介 本文档中指定的 API 使移动应用程序能够访问移动设备中的不同 SE&#xff0c;例如 SIM 或嵌入式 SE。 本规范提供了接口定义和 UML 图&#xff0c;以允许在各种移动平台和不同的编程语言中实现。 如果编程语言支持命名空间&#xff0c;则它应为 org.simalliance.openmob…

Foxit PDF SDK OCR Add-on Library (C++, Windows)-Crk

OCR文档扫描--Crack version 使用Foxit PDF SDK OCR Add-on的光学字符识别&#xff08;OCR&#xff09;软件将扫描的文档转换为可搜索的文本PDF。专为扫描、归档和数字化而设计&#xff0c;我们的插件输出13种不同的文件格式&#xff0c;包括PDF和PDF/A。 在不投资数据输入人员…

Linux 禁用23端口

禁用23端口 前言 23端口是用于Telnet服务的默认端口。Telnet是一种早期的网络协议&#xff0c;允许用户使用一个远程终端连接到远程计算机上&#xff0c;以便在远程计算机上执行命令和操作。通过输入用于Telnet服务器的IP地址和端口号&#xff0c;用户可以在本地计算机上打开一…

【Java|golang】1090. 受标签影响的最大值---关联数组排序问题以及切片排序失败

我们有一个 n 项的集合。给出两个整数数组 values 和 labels &#xff0c;第 i 个元素的值和标签分别是 values[i] 和 labels[i]。还会给出两个整数 numWanted 和 useLimit 。 从 n 个元素中选择一个子集 s : 子集 s 的大小 小于或等于 numWanted 。 s 中 最多 有相同标签的 …

数据结构初阶--栈和队列OJ题

目录 前言有效的括号思路分析代码实现 用队列实现栈思路分析代码实现 用栈实现队列思路分析代码实现 设计循环队列思路分析代码实现 前言 本篇文章将对部分栈和队列综合运用题进行讲解&#xff0c;以对栈和队列有一个更深层次的理解。 有效的括号 先来看题 思路分析 这里…

优秀的流程图应该怎么设计呢?

优秀的流程图应该怎么绘制呢&#xff1f; 本文将带大家学习优秀流程图的绘制要点和技巧&#xff0c;以及讲解流程图与UML活动图、BPMN图之间的关系和区别。 1、认识流程图 流程图简单讲就是用图描述流程&#xff0c;这种流程可以是一种有先后顺序的操作组成&#xff0c;可以…

2024王道数据结构考研丨第六篇:查找、排序

到此&#xff0c;2024王道数据结构考研笔记专栏“基础知识”部分已更新完毕&#xff0c;其他内容持续更新中&#xff0c;欢迎 点此 订阅&#xff0c;共同交流学习… 文章目录 第七章 查找7.1查找表相关概念 第八章 排序8.1排序的基本概念8.2 插入排序8.2.1直接插入排序8.2.2折半…

使用Maven管理项目、导入依赖、测试打包项目、常用依赖

使用Maven管理项目 文章目录 使用Maven管理项目Maven项目结构Maven依赖导入Maven依赖作用域Maven可选依赖Maven排除依赖Maven继承关系Maven常用命令Maven测试项目Maven打包项目 Maven 翻译为"专家"、“内行”&#xff0c;是 Apache 下的一个纯 Java 开发的开源项目。…

hive函数03

自定义函数 Hive 自带了一些函数&#xff0c;比如&#xff1a;max/min等&#xff0c;但是数量有限&#xff0c;自己可以通过自定义UDF来方便的扩展。 在企业中处理数据的时候&#xff0c;对于敏感数据往往需要进行脱敏处理。比如手机号。我们常见的处理方式是将手机号中间4位…

MySQL表设计原则

前言 这里简单整理一些常用的数据库表设计原则以及常用字段的使用范围。 表的设计准则 1、命名规范 表名、字段名必须使用小写字母或者数字&#xff0c;禁止使用数字开头&#xff0c;禁止使用拼音&#xff0c;并且一般不使用英文缩写。主键索引名为 pk_字段名&#xff1b;唯…

SSL/TLS认证握手过程

一: SSL/TLS介绍 什么是SSL,什么是TLS呢&#xff1f;官话说SSL是安全套接层(secure sockets layer)&#xff0c;TLS是SSL的继任者&#xff0c;叫传输层安全(transport layer security)。说白点&#xff0c;就是在明文的上层和TCP层之间加上一层加密&#xff0c;这样就保证上层信…

ACP(MaxCompute篇)-MaxCompute开发工具

创建MaxCompute项目 第一种创建项目方式 1.知道MaxCompute服务。 2.创建项目。 3.创建成功。 第二种创建项目的方式 1.进入DataWorks控制台。 2.创建工作空间。 3.创建的类型。 4.创建计算方式。 5.自定义选择。 6.创建成功。 MaxCompute开发工具简介 Odpscmd 安装配置 下…

java boot项目认识一下三种格式的配置文件

之前我们在 application.properties 中写了很多配置 但boot并不是只有这种配置方式 boot提供了三种配置方式给我们 话不多说 直接上代码 我们先将 resources下的 application.properties给他干掉 然后在下面创建一个 application.yml 在下面编写代码如下 server:port: 81这…