网络编程套接字socket

哈哈哈,之前的保存成草稿忘了发 

目录

一 . 先回顾一下网络初始中的相关概念:

1.网络通信:

2.局域网:

3.广域网:

4.IP地址:

5.端口:

概念

格式

6.协议:

7.五元组:

8.分层协议:

9.封装和分用

10.网络设备分层uuuj

二 . socket

分类

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

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

udp的两个核心类——DatagramSocket和Datagrampacket

UDP的回显服务器

客户端:

 服务器端


一 . 先回顾一下网络初始中的相关概念:

1.网络通信:

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

2.局域网:

Local Area Network,简称LAN。

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

3.广域网:

Wide Area Network,简称WAN

通过路由器,将多个局域网连接起来,在物理上组成很大范围的网络,就形成了广域网。广域网内部的 局域网都属于其子网。

4.IP地址:

用于定位主机 的网络地址。
格式
IP 地址是一个 32 位的二进制数,通常被分割为 4 “8 位二进制数 (也就是 4 个字节),如:
01100100.00000100.00000101.00000110
通常用 点分十进制 的方式来表示,即 a.b.c.d 的形式( a,b,c,d 都是 0~255 之间的十进制整数)。如: 100.4.5.6。
特殊 IP
127.* IP 地址用于本机环回 (loop back) 测试,通常是 127.0.0.1
本机环回主要用于本机到本机的网络通信(系统内部为了性能,不会走网络的方式传输),对于
开发网络通信的程序(即网络编程)而言,常见的开发方式都是本机到本机的网络通信。
IP 地址解决了网络通信时,定位网络主机的问题,但是还存在一个问题,传输到目的主机后, 由哪个进程来接收这个数据呢?这就需要端口号来标识

5.端口:

概念

在网络通信中, IP 地址用于标识主机网络地址,端口号可以标识主机中发送数据、接收数据的进程。简 单说:端口号用于定位主机中的进程
一个网络程序运行的时候就需要绑定一个或者多个端口,后续的通信过程都需要通过端口来进行保证
类似发送快递时,不光需要指定收货地址(IP地址),还需要指定收货人(端口号)
两个不同的进程,不能绑定同一个端口号,但一个进程可以绑定多个端口号。

格式

端口号是0~65535范围的数字,在网络通信中,进程可以通过绑定一个端口号,来发送及接收网络数据。1-1024已经被占用喽(是知名端口号)。64kb

6.协议:

网络协议是网络通信(即网络数据传输) 经过的所有网络设备 都必须共同遵从的一组约定、规则。如怎么样建立连接、怎么样互相识别等。最终体现为在网络上传输的数据包的格式

7.五元组:

TCP/IP 协议中,用五元组来标识一个网络通信:
1. IP :标识源主机
2. 源端口号:标识源主机中该次通信发送数据的进程
3. 目的 IP :标识目的主机
4. 目的端口号:标识目的主机中该次通信接收数据的进程
5. 协议号:标识发送进程和接收进程双方约定的数据格式

8.分层协议:

分层最大的好处,类似于面向接口编程:定义好两层间的接口规范,让双方遵循这个规范来对接。
在代码中,类似于定义好一个接口,一方为接口的实现类(提供方,提供服务),一方为接口的使用类 :
对于使用方来说,并不关心提供方是如何实现的,只需要使用接口即可
对于提供方来说,利用封装的特性,隐藏了实现的细节,只需要开放接口即可
网络编程目标:写一个应用程序让这个程序可以使用网络通信,在这里就需要调用传输层提供的api.传输层api主要是UDP和TCP (socket api);
可以想象一下,公司的各个管理阶层

9.封装和分用

分用就是从物理层出发倒着解开。。

10.网络设备分层

对于一台 主机 ,它的 操作系统 内核实现了从传输层到物理层的内容,也即是 TCP/IP 五层模型的 四层
对于一台 路由器 ,它实现了从网络层到物理层,也即是 TCP/IP 五层模型的 下三层
对于一台 交换机 ,它实现了从数据链路层到物理层,也即是 TCP/IP 五层模型的 下两层
对于 集线器 ,它只实现了 物理层
就看上面9那个图就ok了,路由器下三层,交换机下两层。

二 . socket

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

分类

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

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

TCP ,即 Transmission Control Protocol (传输控制协议),传输层协议。
以下为TCP的特点(细节后续再学习):
有连接
可靠传输
面向字节流
有接收缓冲区,也有发送缓冲区
大小不限
对于字节流来说,可以简单的理解为,传输数据是基于 IO 流,流式数据的特征就是在 IO 流没有关闭的情
况下,是无边界的数据,可以多次发送,也可以分开多次接收。

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

UDP,即User Datagram Protocol(用户数据报协议),传输层协议。
以下为UDP的特点(细节后续再学习):
无连接
不可靠传输
面向数据报
有接收缓冲区,无发送缓冲区
大小受限:一次最多传输64k
对于数据报来说,可以简单的理解为,传输数据是一块一块的,发送一块数据假如 100 个字节,必须一 次发送,接收也必须一次接收100 个字节,而不能分 100 次,每次接收1个字节。
udp的两个核心类——DatagramSocket和Datagrampacket
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口
(一般用于客户端)
DatagramSocket(int port)
创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端)void receive(DatagramPacket p)
从此套接字接收数据报(如果没有接收到数据报,该方法会阻
塞等待)
void send(DatagramPacketp)
从此套接字发送数据报包(不会阻塞等待,直接发送)
void close() 关闭此数据报套接字
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
DatagramPacket(byte[] buf, int length)
构造一个DatagramPacket以用来接收数据报,接收的数据保存在
字节数组(第一个参数buf)中,接收指定长度(第二个参数length)DatagramPacket(byte[]buf, int offset, int length,
SocketAddress address)
构造一个DatagramPacket以用来发送数据报,发送的数据为字节
数组(第一个参数buf)中,从0到指定长度(第二个参数
length)。address指定目的主机的IP和端口号InetAddress getAddress()
从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取
接收端主机IP地址
int getPort()
从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获
取接收端主机端口号
byte[] getData() 获取数据报中的数据
----------------------------------------------------------
构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创
建。
比特就业课
方法签名 方法说明
InetSocketAddress(InetAddress addr, int port) 创建一个Socket地址,包含IP地址和端口号
InetSocketAddress API
InetSocketAddress ( SocketAddress 的子类 )构造方法
UDP的回显服务器
客户端:
package echoserver;import javax.security.auth.login.CredentialException;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
/*
服务器的端口是固定指定的,为了方便用户端找到服务器程序
客户端的端口是系统分配的,如果手动指定可能会有客户端的其他程序端口冲突
服务器不怕冲突,因为服务器上面的程序可控,但是客户端的程序是运行在客户电脑上的,环境是复杂的,不可控服务器要在构造方法中指定好端口*/
public class UdpEchoCLient {public DatagramSocket socket = null;//构造这个对象不需要显式的绑定一个端口,让操作系统自动分配端口(随机挑选一个空闲的)//对于服务器:端口必须是确定好的//对于客户端来说,端口可以是系统分配的//一次通信涉及到的IP和端口://端口号用来标识/区分一个进程,因此不允许一个端口同时被多个进程使用(同一个主机上)//源IP和目的IP,yuan端口和目的端口//发送方为源,接收方为目的//由于客户端和服务器都在一个主机上,IP都是127.0.0.1(环回IP),端口是指定了的private String serverIP = null;private int serverPort = 0;//IP是已知的127.0.0.1//    port是自动分配的//服务器的IP和端口号也要告诉客户端,才能顺利把消息发给服务器public UdpEchoCLient(String serverIP, int serverPort) throws SocketException {socket = new DatagramSocket();this.serverIP = serverIP;this.serverPort = serverPort;}public void start() throws IOException {System.out.println("客户端启动");Scanner scanner = new Scanner(System.in);while(true){//1.从控制台读取数据System.out.println("> ");String request = scanner.next();if(request.equals("exit")){System.out.println("byebye");break;}//2.构造成UDP请求并发送//传入的serverIP是一个字符串,点分十进制的,而IP地址需要传入一个32位的整数形式,// InetAddress.getByName进行转换DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIP),serverPort);socket.send(requestPacket);//3.读取服务器的UDP响应,并解析DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//4.把解析好的结果展示出来String response = new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoCLient cLient = new UdpEchoCLient("127.0.0.1",1090);cLient.start();}
}
 服务器端
package echoserver;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//UDP版本的回显服务器
public class UdpEchoServer {/*网络编程本质上是操作网卡但是网卡不方便直接操作,在操作系统内核中使用了特殊的文件"socket"来抽象地表示网卡因此进行网络通信,势必需要创造一个socket对象*/private DatagramSocket socket = null;/*服务器必须知道哪个端口,例如饭堂卖重庆小面的在11窗口,方便客户找,11就是指定的端口对于服务器来说必须要在创建socket对象的时候给绑定一个具体的端口号否则无法通信!*/public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);}public void start() throws IOException {System.out.println("服务器启动!!");//要注意服务器是不止给一个客户端服务的//while会快速循环while(true){//这里的死循环是必须的,因为服务器就是要一直运行,等待客户端的请求,除了个别服务器,像12306//每天都会定时维护//只要有客户端过来就可以提供服务//1.读取客户端的请求//receive方法参数是输出型参数.//输出型参数.不是我们传数据然后方法使用,而是我i们传进去一个空壳让方法填充数据再返回//receive方法接收请求需要先构造一个空白的DatagramPacket对象,然后交给receive来填充DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);//客户端发请求了receive就顺利读出,如果没有发送请求,此时receive就阻塞,类似与Scanner读取控制台的操作//客户端请求太多处理不过来也就是"高并发"//处理高并发:多线程/多加机器(管理成本提高--分布式)socket.receive(requestPacket);//🎶输出型参数//receive 内部会针对参数对象填充数据.//填充的数据来自于网卡,从网卡读完,填充到对象中//此时requestPacket中包含的数据不方便直接处理,是一个特殊的对象,我们将它转换成字符串就好处理了String request = new String(requestPacket.getData(),0,requestPacket.getLength());//requestPacket.getLength()是获取到实际的数据的长度,避免浪费//可能这个数据报转换成字符串后长度很小,我们就只构造相应的长度,而不是构造byte[]数组那么长的字符串//2.根据请求,计算响应,这里是回显服务器,响应和请求相同String response = process(request);//3.把响应写回客户端//使用send方法,参数也是DatagramPacket,需要先构造好对象//响应对象要使用响应数据来构造,不能是空的DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());/*此处的长度使用response.length()和response.getBytes().length有什么区别呢??两个写法计量单位不同,一个是字节的个数,一个是字符的个数,如果存的数据都是ASCII的数据就没差别但是如果存的汉字,那结果就大相径庭socket api本来就是按照字节来算DatagramPacket是按字节来处理的,所以我们要计算的是响应数据的字节个数___________________requestPacket.getSocketAddress()是客户端的IP和端口号*///发送socket.send(responsePacket);//4.打印中间结果System.out.printf("[%s:%d] req: %s; resp: %s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);//}}//计算响应public String process(String request){return request;}public static void main(String[] args) throws IOException {//端口号可以随意指定//范围:1024-65535UdpEchoServer server = new UdpEchoServer(1090);server.start();/*理解服务器的工作流程1.读取请求并解析2.根据请求计算响应3.构造响应并写回给客户端*/}
}

 翻译单词程序

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;//继承服务器,重写process方法
public class UdpDictServer extends UdpEchoserver2{private Map<String,String> dict = new HashMap<>();public UdpDictServer(int port) throws SocketException {super(port);dict.put("hello","你好");dict.put("world","世界");dict.put("big","大");dict.put("deprive","剥夺剥削");}@Overridepublic String process(String request) {return dict.getOrDefault(request,"没有查到!");}public static void main(String[] args) throws IOException {UdpDictServer udpDicyServer = new UdpDictServer(1090);udpDicyServer.start();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【cesium-4】cesium空间数据加载与管理

目录 一、cesium空间数据加载 1、cesium画线 2、cesium绘制矩形 3、cesium绘制平面 4、飞机模型加载 5、标签加载 6、cesium绘制多边形 二、cesium空间数据管理 一、cesium空间数据加载 空间数据包括&#xff1a; 矢量数据&#xff1a;几何体、模型、标签等&#xff…

如何使用支付宝沙箱环境支付并公网调用sdk创建支付单服务

文章目录 1.测试环境2.本地配置2. 内网穿透2.1 下载安装cpolar内网穿透2.2 创建隧道3. 测试公网访问4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名5. 使用固定二级子域名进行访问 1.测试环境 MavenSpring bootJdk 1.8 2.本地配置 获取支付宝支付Java SDK,…

单片机第三季-第七课:STM32中断体系

目录 1&#xff0c;NVIC 2&#xff0c;中断和事件的区别 3&#xff0c;优先级的概念 4&#xff0c;如何实际编程使用外部中断 5&#xff0c;STM32开发板通过按键控制LED 5.1&#xff0c;打开相应GPIO模块时钟 5.2&#xff0c;NVIC设置 5.3&#xff0c;外部中断线和配套…

【网络奇缘】——奈氏准则和香农定理从理论到实践一站式服务|计算机网络

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 失真 - 信号的变化 影响信号失真的因素&#xff1a; ​编辑 失真的一种现象&#xff1a;码间…

udp多播/组播那些事

多播与组播 多播&#xff08;multicast&#xff09;和组播&#xff08;groupcast&#xff09;是相同的概念&#xff0c;用于描述在网络中一对多的通信方式。在网络通信中&#xff0c;单播&#xff08;unicast&#xff09;是一对一的通信方式&#xff0c;广播&#xff08;broad…

Azure Machine Learning - Azure OpenAI GPT 3.5 Turbo 微调教程

本教程将引导你在Azure平台完成对 gpt-35-turbo-0613 模型的微调。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕&#xff0c;复旦机器人智能实验室成员&#xff0c;阿里云认证的资深架构师&…

使用travelbook架设自己的实时位置共享服务

travelbook 是一款开源的安卓APP&#xff0c;它能以低功耗提供实时位置共享&#xff0c;它包含功能如下&#xff1a; 好友之间分享实时位置&#xff1b;记录行程轨迹&#xff1b;标记收藏地点&#xff1b; 这款软件的主要解决的问题包括&#xff1a; 场景1&#xff1a;查看老…

云原生系列3-Kubernetes

1、Kubernetes概述 k8s缩写是因为k和s之间有八个字符。k8s是基于容器技术的分布式架构方案。官网&#xff1a;https://kubernetes.io/zh-cn/ Google在 2014年开源了Kubernetes项目&#xff0c;Kubernetes是一个用于自动化部署、扩展和管理容器化应用程序的开源系统。同样类似的…

智能优化算法应用:基于原子轨道搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于原子轨道搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于原子轨道搜索算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.原子轨道搜索算法4.实验参数设定…

uniapp在中app,登录页能记住多个账号以及密码功能完整代码

如图所示&#x1f447;&#xff1a; 1.可以选择下拉&#xff0c;选取曾经登录成功的账户&#x1f447; 2.选择好下拉后自动赋值&#xff0c;账号密码。 3.勾选记住我则记住该账户以及密码 4.选择下拉后&#xff0c;点选删除账户&#xff0c;则删除 <template><view…

【数据结构和算法】找到最高海拔

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 前缀和的解题模板 2.1.1 最长递增子序列长度 2.1.2 寻找数组中第 k 大的元素 2.1.3 最长公共子序列…

设计模式 建造者模式 与 Spring Bean建造者 BeanDefinitionBuilder 源码与应用

建造者模式 定义: 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示主要作用: 在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象如何使用: 用户只需要给出指定复杂对象的类型和内容, 建造者模式负责按顺序创建复杂对象…

ZooKeeper Client API 安装及使用指北

下载 wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.4-beta/zookeeper-3.5.4-beta.tar.gz解压 tar -zxf zookeeper-3.5.4-beta.tar.gz安装 cd zookeeper-3.5.4-beta/src/c/ ./configure make sudo make install到 make 这一步大概率会出现报错&#xff1a;…

几种串口扩展电路

一、IIC串口扩展电路 LCT200 是一款可以通过 I2C 接口通讯&#xff0c;拓展 2 路独立串口的通讯芯片&#xff0c;同时也支持通过 2 路串口读写 I2C 接口的数据。LCT200 的封装为 TSSOP-20。 主要功能&#xff1a;⚫ 通过对 I2C 接口读写实现拓展 2 路独立串口功能 ⚫ 通过读写…

计算机毕业设计 基于SpringBoot的高校宣讲会管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

手把手从0开始SpringBoot多模块项目搭建

最近起个小项目&#xff0c;用多模块搭建一下&#xff0c;顺便记录分享 1.创建父工程 通过Spring Lnitalizer创建&#xff0c; 我这里使用的是 springboot 2.7.3 jdk11 创建好后删除刚创建工程里不需要的文件&#xff0c; 只保留&#xff1a;.idea 文件夹 、项目 pom 文件、…

微服务概念

1.什么是微服务&#xff1f; 顾名思义&#xff0c;是一个微小的服务&#xff0c;为什么会说是“ 微 ” 呢&#xff1f; 意思整个服务的是比较微小的&#xff0c;是一个独立的业务模块&#xff0c;专做改业务的事情&#xff0c;是一个独立的功能单元。 一种独特的架构设计模式&…

【python】python课设 天气预测数据分析及可视化(完整源码)

目录 1. 前言2. 项目结构3. 详细介绍3.1 main.py3.2 GetModel.py3.3 GetData.py3.4 ProcessData.py3.5天气网.html 4. 成果展示 1. 前言 本文介绍了天气预测数据分析及可视化的实现过程使用joblib导入模型和自定义模块GetModel获取模型&#xff0c;输出模型的MAE。使用pyechart…

Java基于TCP网络编程的群聊功能

服务端 import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List;public class Server2 {public static List<Socket> onlineList new ArrayList<>();public static void main(String[] args) throws Except…

格密码:傅里叶矩阵

目录 一. 铺垫性介绍 1.1 傅里叶级数 1.2 傅里叶矩阵的来源 二. 格基与傅里叶矩阵 2.1 傅里叶矩阵详细解释 2.2 格基与傅里叶矩阵 写在前面&#xff1a;有关傅里叶变换的解释太多了&#xff0c;这篇博客主要总结傅里叶矩阵在格密码中的运用。对于有一定傅里叶变换基础的同…