网络编程套接字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-65535
        UdpEchoServer 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","剥夺剥削");
    }
    @Override
    public String process(String request) {
            return dict.getOrDefault(request,"没有查到!");
    }
    public static void main(String[] args) throws IOException {
        UdpDictServer udpDicyServer = new UdpDictServer(1090);
        udpDicyServer.start();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

恶意软件分析沙箱在网络安全策略中处于什么位置?

恶意软件分析沙箱提供了一种全面的恶意软件分析方法&#xff0c;包括静态和动态技术。这种全面的评估可以更全面地了解恶意软件的功能和潜在影响。然而&#xff0c;许多组织在确定在其安全基础设施中实施沙箱的最有效方法方面面临挑战。让我们看一下可以有效利用沙盒解决方案的…

[足式机器人]Part4 南科大高等机器人控制课 CH10 Bascis of Stability Analysis

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;CLEAR_LAB 笔者带更新-运动学 课程主讲教师&#xff1a; Prof. Wei Zhang 南科大高等机器人控制课 Ch10 Bascis of Stability Analysis 1. Background1.1 What is Stability Analysis1.2 General ODE Models for Dynamic…

162TB全球卫星地图瓦片服务

这里再为你分享长光的另一款重量级产品&#xff0c;即《吉林一号国产化全球遥感底图瓦片服务》&#xff0c;你可以把它简单地理解为是一套全球离线地图服务系统。 为了行文方便&#xff0c;我们在本文暂且称之为“长光全球瓦片系统”。 《长光全球瓦片系统》参数 《长光全球…

电脑屏幕保护时间怎么设置?这4个方法很管用!

“我的工作经常都需要使用电脑&#xff0c;有时候使用时间比较长&#xff0c;会有眼睛疲惫的感觉。想问问电脑屏幕保护时间应该怎么设置呢&#xff1f;有什么可以快速对电脑屏幕保护时间进行设置的方法吗&#xff1f;” 在现代生活中&#xff0c;电脑已经成为我们不可或缺的工具…

OpenAI大模型DecryptPrompt

what is prompt 综述1.Pre-train, Prompt, and Predict: A Systematic Survey of Prompting Methods in Natural Language Processing(五星好评)综述2. Paradigm Shift in Natural Language Processing(四星推荐)综述3. Pre-Trained Models: Past, Present and Future Prompt即…

服务器数据恢复-raid6离线磁盘强制上线后分区打不开的数据恢复案例

服务器数据恢复环境&#xff1a; 服务器上有一组由12块硬盘组建的raid6磁盘阵列&#xff0c;raid6阵列上层有一个lun&#xff0c;映射到WINDOWS系统上使用&#xff0c;WINDOWS系统划分了一个GPT分区。 服务器故障&分析&#xff1a; 服务器在运行过程中突然无法访问。对服务…

C++入门编程二(各类运算符、if、switch、while、for循环等语句)

文章目录 算术运算符前后置运算符赋值运算符比较运算符逻辑运算符if语句1、单行if2、多行if3、多条件if4、嵌套if语句5、案例&#xff1a;三只小猪称体重 三目运算符switch语句while循环语句案例&#xff1a;1、猜数字 do-while循环语句案例&#xff1a;1、水仙花数 for循环语句…

SAP CO系统配置-获利能力分析-(机器人制造项目实例)

创建经营组织 配置路径 IMG菜单路径:企业结构>定义>控制>创建经营组织 事务代码 KEP8 屏幕截图: 维护特性 配置路径

有没有好用的视频提取文案工具推荐?

在如今这个快节奏的时代中&#xff0c;视频已成为人们记录和分享生活的重要媒介。当然有很多优秀的人&#xff0c;它们创作的视频文案或是演讲的台词、字幕等都非常精彩&#xff1b;难免有时候我们也会借鉴他人的优质内容供自己参考、修改等。那么怎么把这些内容自动提取出来呢…

气动冷凝水回收泵机械浮球泵的特点工作原理介绍 不需要电源

​ 1&#xff1a;气动凝水回收泵机械式介绍 气动冷凝水回收泵是一种设计用于不使用电力来泵送冷凝液、油和其他高温液体等的设备。它无需维护&#xff0c;能将大量凝结水和其它液体从低位、低压或真空场所泵送到高处及高压区域。与传统电泵相比&#xff0c;气动冷凝水回收泵可…

【51单片机系列】DS18B20温度传感器模块

本文是关于温度传感器的相关内容。 文章目录 一、 DS18B20数字温度传感器介绍1.1、 DS18B20温度传感器的特点1.2、DA18B20内部结构1.3、 DS18B20的温度转换规则1.4、 DS18B20的ROM指令表1.6、 计算温度1.7、 读写时序 二、DS18B20使用示例 一、 DS18B20数字温度传感器介绍 DS1…

el-date-picker月选择器获取选择的日期范围

<el-date-pickerv-model"monthValue"type"month"placeholder"选择月"value-format"yyyy-MM-dd"change"monthChange"> </el-date-picker> ​monthChange(val) {const [year, month, day] val.split(-) // 获取对…

视频遥测终端机的设计需求

目录 1.目的 2.参考文件 3.总体描述 4.硬件资源描述 4.1微控制单元 4.2视频处理单元 4.3性能指标 5.功能要求 5.1系统参数要求 5.1.1系统管理 5.1.2系统配置 5.1.2.1一般参数 5.1.2.2编码参数 5.1.2.3网络参数 5.1.2.4网络服务 5.1.2.5OSD参数 5.1.2.6抓拍 5.…

Pytorch深度强化学习2-1:基于价值的强化学习——DQN算法

目录 0 专栏介绍1 基于价值的强化学习2 深度Q网络与Q-learning3 DQN原理分析4 DQN训练实例 0 专栏介绍 本专栏重点介绍强化学习技术的数学原理&#xff0c;并且采用Pytorch框架对常见的强化学习算法、案例进行实现&#xff0c;帮助读者理解并快速上手开发。同时&#xff0c;辅…

基于电商场景的高并发RocketMQ实战-Raft协议的leader选举算法、Broker基于状态机实现的leader选举

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 【11来了】文章导读地址&#xff1a;点击查看文章导读&#xff01; &#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f3…

使用LLaMA-Factory微调ChatGLM3

1、创建虚拟环境 略 2、部署LLaMA-Factory &#xff08;1&#xff09;下载LLaMA-Factory https://github.com/hiyouga/LLaMA-Factory &#xff08;2&#xff09;安装依赖 pip3 install -r requirements.txt&#xff08;3&#xff09;启动LLaMA-Factory的web页面 CUDA_VI…

Mybatis如何兼容各类日志?

文章目录 适配器模式日志模块代理模式1、静态代理模式2、JDK动态代理 JDBC Logger总结 Apache Commons Logging、Log4j、Log4j2、java.util.logging 等是 Java 开发中常用的几款日志框架&#xff0c;这些日志框架来源于不同的开源组织&#xff0c;给用户暴露的接口也有很多不同…

ResNet网络分析与demo实例

参考自 up主的b站链接&#xff1a;霹雳吧啦Wz的个人空间-霹雳吧啦Wz个人主页-哔哩哔哩视频这位大佬的博客 Fun_机器学习,pytorch图像分类,工具箱-CSDN博客 ResNet 详解 原论文地址 [1512.03385] Deep Residual Learning for Image Recognition (arxiv.org) ResNet 网络是在 …

Python、PHP/JAVA/C#电商评论数据采集与分析

引言 在电商竞争日益激烈的情况下&#xff0c;商家既要提高产品质量&#xff0c;又要洞悉客户的想法和需求&#xff0c;关注客户购买商品后的评论&#xff0c;而第三方商家获取商品评价主要依赖于人工收集&#xff0c;不但效率低&#xff0c;而且准确度得不到保障。通过使用Py…

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

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