【JavaEE初阶系列】——网络编程 UDP客户端/服务器 程序实现
目录
🚩UDP和TCP之间的区别
🎈TCP是有连接的 UDP是无连接的
🎈TCP是可靠传输 UDP是不可靠传输
🎈TCP是面向字节流 UDP是面向数据报
🎈TCP和UDP是全双工
👩🏻💻UDP的socket api使用
💻DatagramSocket API
💻DatagramSocket 方法
💻DatagramPacket API
💻InetSocketAddress API
🎓UDP客户端/服务器 通信程序实现
🔴服务器
📝接收客户端发来的请求,并且解析
📝根据请求返回响应
📝创建一个DatagramPacket类, 存入数据,并发送给客户端
📝打印日志
🔴客户端
通过网络,让俩个主机之间进行通信,基于这样的通信来完成一定的功能。
进行网络编程的时候,需要操作系统给咱们提供一组api,通过这种api才能完成编程。
api可以认为是应用层和传输层之间交互的路径。socket api就相当于插座一样,通过这一套socket api可以完成不同软件之间,不同操作系统之间的通信。
传输层,提供的协议,主要有2个,TCP和UDP这俩个。TCP和UDP这俩个协议的特性(工作原理) 差异很大,导致,使用俩种协议进行网络编程,也存在一定差别,系统就分别提供俩种api。
🚩UDP和TCP之间的区别
🎈TCP是有连接的 UDP是无连接的
TCP是有连接的,UDP是无连接的。什么是有连接和无连接呢?此处的连接本质上就是建立连接的双方,各自保存对方的信息,俩台计算机建立连接,就是双方彼此保存了对方的关键信息。TCP要想通信,就需要先建立连接(所谓连接就是保存对方的信息),做完之后,才能后续通信。(如果A和B建立连接,但是B拒绝了,通信就无法完成了),UDP想要通信,就直接发送数据就行了,不需要建立连接,也就是不需要保存对方的信息。虽然UDP本身是不保存的,但是你调用的UDP的socket api的时候要把对方的位置啥的给传过去。后面再 实现TCP就需要在类里初始化IP地址和端口号传入构造方法中,而UDP不用。
🎈TCP是可靠传输 UDP是不可靠传输
TCP里面内置了可靠传输的机制,UDP没有。网络上进行通信,A发送给B消息,这个消息不可能做到100%发送到的,所以什么是可靠传输呢?可靠传输就是A发送给B发信息,消息是不是到达B这一方,A自己能感知到(A心里有数)进一步的,就可以再发送失败的时候采取一定的措施(尝试重传之类的)。而从不可靠传输到可靠传输都是需要付出一些代价的,比如可靠传输的机制比较复杂,传输效率低。
就像一个老中医生有资历给病人看病,看了一下就知道他有什么毛病,只是不说出来,老中医心里有数,然后就去拿药配方进行医治。
🎈TCP是面向字节流 UDP是面向数据报
字节流和文件操作里面的字节流是一个意思,所以我们再实现TCP客户端和服务器之间的通信的时候,就需要用到文件操作里面字节输入流和输出流。
- TCP是和文件操作一样,以字节为单位来进行传输
- UDP是按照数据报为单位,来进行传输的。UDP数据报是有严格的格式的。
🎈TCP和UDP是全双工
- 一个信道,允许双向通信,就是全双工
- 一个信道,只能单向通信,就是半双工
代码中使用一个Socket对象,就可以发送数据也能接收数据。
半双工——单向通信
一个管子,只能一边吹气。
但是B 不能给A吹气 ,这就是所谓的单向通信——半双工
全双工——双向通信
一根网线,电流不是只能从一边流向另一边,咋能双向通信呢?
就比如一个道路,我们中间划一道黄线,双向行驶
👩🏻💻UDP的socket api使用
💻DatagramSocket API
方法签名 | 方法说明 |
DatagramSocket() | 创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端) |
DatagramSocket(int port) | 创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务器) |
为什么服务器要指定端口呢?而客户端不同?
因为服务器是程序员决定的,知道哪些端口是可以用的,这是可控的,客户端是不可控的,每个用户电脑程序不一样,占用的端口也不一样,如果手动指定端口,会产生冲突。所以 客户端交给系统自动分配的。
socket其实也是操作系统一个概念,本质上是一种特殊的文件,Socket就属于是把"网卡"这个设备,抽象成了文件了,往socket文件中写数据,就相当于通过网卡发送数据,从socket文件读数据,就相当于通过网卡接收数据。这就是网络通信和文件操作统一了。
💻DatagramSocket 方法
方法签名 | 方法说明 |
void receive(DatagramPacket p) | 从此套接字接收数据报(如果没有接收到数据报,该方法就会阻塞等待) |
void send(DatagramPacket p) | 从此套接字发送数据报包(不会阻塞等待,直接发送) |
void close() | 关闭此数据报套接字 |
receive()和send()方法里面的参数其实是输出型参数,数据报是空的,然后进行填充,并返回。
💻DatagramPacket API
方法签名 | 方法说明 |
DatagramPacket(byte[] buf,int length) | 构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组(第一个参数buf)中,接收指定长度(第二个参数length) |
DatagramPacket(byte[] buf,int offset,int length,SocketAddress address) | 构造一个DatagramPacket以用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从0到指定长度(第二个参数length)。address指定目的主机的IP和端口号 |
DatagramPacket 方法:
方法签名 | 方法说明 |
InetAddress. getAddress() | 从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址 |
int getPort() | 从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号 |
byte[] getData() 获取数据报中的数据
构造UDP发送的数据报时,需要传入socketAddress,该对象可以使用InetSocketAddress来创建。
💻InetSocketAddress API
方法签名 | 方法说明 |
---|---|
InetSocketAddress(InetAddress addr, int port) | 创建一个Socket地址,包含IP地址和端口号 |
🎓UDP客户端/服务器 通信程序实现
这个程序是没有什么业务逻辑,只是单纯的调用socket api .让客户端给服务器发送一个请求,请求就是一个从控制台输入的字符串,服务器收到字符串之后,也就会把这个字符串原封不动的返回客户端,客户端再显出来。——回显服务器(echo server)
🔴服务器
📝接收客户端发来的请求,并且解析
public UdpEchoServer(int port) throws SocketException {socket=new DatagramSocket(port);//服务器需要指定端口}
服务器和客户端都需要创建Socket对象。
- 服务器的socket一般要显示的指定一个端口号
- 客户端的socket一般不能显式指定(不显示指定,此时系统会自动分配一个随机的端口)
//接收请求之前,我们需要开辟一个空间存储要求DatagramPacket requestSocket=new DatagramPacket(new byte[4096],4096);socket.receive(requestSocket);
DatagramPacket这个对象用来承载从网卡这边读到的数据,收到数据的时候,需要搞一个内存空间来保存这个数据,DatagramPacket内部不能自行分配内存空间,因此就需要程序员手动把孔吉纳创建好,交给DatagramPacket进行处理。
服务器一旦启动,就会立即执行到这里的receive方法,此时客户端的请求还没来,这种情况也是没有关系的,receive就会直接阻塞,就会一直阻塞到真正客户端把请求发过来为止。
//由于接收到的请求是二进制,我们需要转换成字符串String request=new String(requestSocket.getData(),0,requestSocket.getLength());
这个getLength 得到的结果是否是上述的4096?这个结果是收到的数据的真实长度(取决于发送方这一次到底发送了多少数据。取这个区间内的字节,构成一个Stirng。
📝根据请求返回响应
//2.根据请求返回响应String response=new String(request);
public String process(String request){return request;}
这个步骤是一个服务器程序,最核心的步骤!咱们当时是echo server不涉及这些流程,也不必考虑响应怎么计算,只要请求过来,就把请求当作响应。
📝创建一个DatagramPacket类, 存入数据,并发送给客户端
UDP是无连接的,UDP自身不会保存数据要发给谁,就需要每次发送的时候,重新指定,数据要发到哪里去。上述创建数据报是存入发来的请求。
//3.创建一个DatagramPacket类, 存入数据,并发送给客户端//requestSocket.getSocketAddress() requestSocket里面包含客户端的IP地址和端口号DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),0,response.getBytes().length,requestSocket.getSocketAddress());socket.send(responsePacket);
构造这个数据报,需要指定数据内容,也指定一下数据报要发给谁。再网络传输的时候,肯定是要使用字节的。
可以让response.getBytes().length改成response.length()嘛?不行的,本质上也是和字符集有关系的。如果你这个字符串里内容都是英文字符,此时字节和字符个数是一样的,如果包含中文就不一样的。
requestSocket.getSocketAddress()指定一下请求中的地址(数据从哪里来,我们就要到哪里去)包含IP地址和端口号
📝打印日志
//打印一个日志 打印 客户端IP 客户端端口 客户端内容 服务器内容System.out.printf("[%s:%d] %s,%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);
package UDP;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpEchoServer {DatagramSocket socket=null;public UdpEchoServer(int port) throws SocketException {socket=new DatagramSocket(port);//服务器需要指定端口}public void start() throws IOException {System.out.println("服务器开始启动->");while (true){//1.接收客户端发来的请求,并且解析//接收请求之前,我们需要开辟一个空间存储要求DatagramPacket requestSocket=new DatagramPacket(new byte[4096],4096);//然后接收请求(如果客户端还没发来请求,就阻塞等待)socket.receive(requestSocket);//由于接收到的请求是二进制,我们需要转换成字符串String request=new String(requestSocket.getData(),0,requestSocket.getLength());//2.根据请求返回响应String response=new String(request);//3.创建一个DatagramPacket类, 存入数据,并发送给客户端//requestSocket.getSocketAddress() requestSocket里面包含客户端的IP地址和端口号DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),0,response.getBytes().length,requestSocket.getSocketAddress());socket.send(responsePacket);//打印一个日志 打印 客户端IP 客户端端口 客户端内容 服务器内容System.out.printf("[IP地址:%s 端口号:%d] request=%s response=%s",responsePacket.getAddress(),responsePacket.getPort(),request,response);}}public String process(String request){return request;}public static void main(String[] args) throws IOException {UdpEchoServer udpEchoServer=new UdpEchoServer(9090);udpEchoServer.start();}
}
🔴客户端
客户端做的事情就是 发出请求,尝试得到服务器返回的响应
- 1.将输入的字符串转换成请求,并发送给服务器
- 2.发出请求之后,我们就要创建一个数据报,存储由服务器返回的请求,尝试返回请求
- 3.将响应转换成字符串,并响应出来
package UDP;import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UDPClient {DatagramSocket socket=null;String serverIp="";int serverPort=0;public UDPClient(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.将输入的字符串转换成请求,并发送给服务器String request=scanner.next();DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);socket.send(requestPacket);//2.尝试返回服务器的响应DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//3.将响应转换成字符串,并响应出来String response=new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UDPClient udpClient=new UDPClient( "10.41.90.105",9090);udpClient.start();}
}
🔴服务器/客户端通信流程
我们写完UDP的服务器和客户端的代码之后,为什么不close?就是关闭数据报套接字
socket也是文件,不关闭就会出问题了,就会出现文件资源泄漏嘛?(资源泄漏就是代码中频繁的打卡文件,但是不关闭,在一个进程的运行过程中,不断积累打开的文件,逐渐消耗掉文件描述符表里的内容,最终就消耗没了,如果进程的生命周期很短,打开一下没多久就关闭了,谈不上泄漏)
socket是文件描述符表中的一个表项,每次打开一个文件,就要占用一个位置。文件描述符,是在pdb上的。(跟随进程的)
这个socket在整个程序运行过程中都是需要使用的(不能提前关闭)当socket不需要使用的时候,意味着程序就要结束了,进程结束,此时随之文件描述符就会销毁了(pcb都销毁了)。随着销毁的过程,被系统自动回收了。
先启动服务器,再启动客户端
🍭 基于echo server写一个翻译服务器
请求的是一个英文单词,响应就会返回对应的中文翻译。
cat——》小猫
dog——》小狗
通过代码来实现
public class UdpDicServer extends UdpEchoServer {private Map<String,String> dict=new HashMap<>();public UdpDicServer(int port) throws SocketException {super(port);}
}
用哈希表 来记录键值对,key是英文单词,value是英文单词的翻译,构成了键值对。
然后我们继承了服务器的类,我们要先调用他的构造方法。然后进行初始化。
package UDP;import javax.rmi.CORBA.Util;
import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;public class UdpDicServer extends UdpEchoServer {private Map<String,String> dict=new HashMap<>();public UdpDicServer(int port) throws SocketException {super(port);//此时往这个表中插入几千几万个英文单词dict.put("cat","猫");dict.put("dog","狗");dict.put("flower","花");}//重写process方法,再重写的方法中完成翻译的过程//翻译的本质是“查表"public String process(String request){return dict.getOrDefault(request,"该词在该词典中不存在");}public static void main(String[] args) throws IOException {UdpDicServer server=new UdpDicServer(9090);server.start();}
}
start方法中,调用process方法,this.process。
当前是子类引用调用start,this就是指向子类引用,虽然this是父类的类型,但是实际指向的是子类引用,调用process自然就会执行到子类的方法中, 上述重写了process方法,就可以在子类中组织你想要的”业务逻辑“。
只要跑得足够久,所有的雨都是阵雨。
相关文章:
【JavaEE初阶系列】——网络编程 UDP客户端/服务器 程序实现
目录 🚩UDP和TCP之间的区别 🎈TCP是有连接的 UDP是无连接的 🎈TCP是可靠传输 UDP是不可靠传输 🎈TCP是面向字节流 UDP是面向数据报 🎈TCP和UDP是全双工 👩🏻💻UDP的socket ap…...
数据结构复习指导之绪论(算法的概念以及效率的度量)
文章目录 绪论: 2.算法和算法评价 知识总览 2.1算法的基本概念 知识点回顾与重要考点 2.2算法效率的度量 知识总览 1.时间复杂度 2.空间复杂度 知识点回顾与重要考点 归纳总结 绪论: 2.算法和算法评价 知识总览 2.1算法的基本概念 算法( Al…...
C语言经典例题(23)
1.求n的阶乘。(不考虑溢出) #include <stdio.h>int fac(int n);int main() {int n 0;scanf("%d", &n);int sum fac(n);printf("%d", sum);return 0; }int fac(int n) {if (n > 1){return n * fac(n - 1);}elsereturn 1; }2.求第n个斐波那契…...
Gitea的简单介绍
Gitea 是一个自由、开源、轻量级的 Git 服务程序。它是为了建立一个易于使用的、类似 GitHub 的 Git 服务而创建的。Gitea 采用 Go 语言编写,具有简单、快速、易于安装和配置的特点。 Gitea 提供了一个基本的 Web 界面,可以方便地进行代码托管、问题跟踪、协作等操作。用户可…...
Qt信号与槽
我们在使用Qt的时候,不使用Qt Designer 的方式进行开发,使用ui文件,信号与槽的连接方式是生成代码之后才能在setupUi函数里才能看到,或者需要进入Ui设计器里的信号槽模式里才能看到信号槽的连接。所以我们最好使用代码绘制界面。 …...
QQ农场-phpYeFarm添加数据教程
前置知识 plugin\qqfarm\core\data D:\study-project\testweb\upload\source\plugin\qqfarm\core\data 也就是plugin\qqfarm\core\data是一个缓存文件,如果更新农场数据后,必须要删除才可以 解决种子限制(必须要做才可以添加成功) 你不更改加入了id大于2000直接删除种子 D…...
Java中创建多线程的方法
继承Thread类,对该类进行new一个实例,对实例调用start方法,重写run方法。 缺点:单继承,无法继承 public class myThread extends Thread {public static void main(String[] args) {myThread myThread new myThread()…...
MT3020 任务分配
思路:利用二分找到某个时间是满足“k个人可以完成” ,并且时间最小。 因为尽量让后面的人做任务,所以从后往前排任务(倒着分配)。从后往前遍历任务,如果此人加上这个任务超出之前求得的时间,就…...
【Redis】事务
Redis事务是一组命令的集合。这组命令顺序化执行而不会被其他命令插入。 Redis事务命令 命令描述DISCARD取消事务,放弃执行EXEC执行事务MULTI标记事务的开始UNWATCH取消WATCH对所有key的监控WATCH监控所有key Redis事务特点 特点说明单独的隔离操作Redis命令执行…...
每日一题(leetcode238):除自身以外数组的乘积--前缀和
不进阶是创建两个数组: class Solution { public:vector<int> productExceptSelf(vector<int>& nums) {int nnums.size();vector<int> left(n);vector<int> right(n);int mul1;for(int i0;i<n;i){mul*nums[i];left[i]mul;}mul1;for…...
内网通如何去除广告,内网通免广告生成器
公司使用内网通内部传输确实方便!但是会有广告弹窗推送!这个很烦恼!那么如何去除广告呢! 下载: 链接:https://pan.baidu.com/s/1CVVdWexliF3tBaFgN1W9aw?pwdhk7m 提取码:hk7m ID:…...
视频知识整理
1 视频播放器原理 视频播放器播放一个互联网上的视频文件,需要经过以下几个步骤: 解协议:将流媒体协议的数据,解析为标准的相应的封装格式数据 解封装:将封装格式的数据,分离成为音频流压缩编码数据和视…...
【2024】使用Rancher管理k8s集群和创建k8s集群
Rancher管理k8s集群及创建k8s集群。 Rancher版本为:2.8.2目录 rancher管理k8s集群rancher创建k8s集群rancher管理k8s集群 使用rancher管理已经存在的k8s集群。 本部分内容需要自行准备好k8s集群及rancher平台,部署请看本人其他文章 。 登录到rancher平台后,点击集群管理,…...
生成对抗网络 – Generative Adversarial Networks | GAN
目录 生成对抗网络 GAN 的基本原理 非大白话版本 第一阶段:固定「判别器D」,训练「生成器G」...
基于深度学习的生活垃圾智能分类系统(微信小程序+YOLOv5+训练数据集+开题报告+中期检查+论文)
摘要 本文基于Python技术,搭建了YOLOv5s深度学习模型,并基于该模型研发了微信小程序的垃圾分类应用系统。本项目的主要工作如下: (1)调研了移动端垃圾分类应用软件动态,并分析其优劣势;分析了深…...
软件包名生成参考
服务名称-分支名称-最后提交时间(精确到秒)-最后提交-编译时间(unix时间戳) 示例:crm_5.2_221024-221020160306-b846f829-1665655859 包名生成脚本参考: 分支名称 export GIT_BRANCH$(git branch|grep "\*"|head -n1|awk {print $NF})git最…...
八大排序算法(面试被问到)
1.八大排序算法都是什么? 八大排序算法有:插入排序、冒泡排序、归并排序、选择排序、快速排序、希尔排序、堆排序、基数排序(通常不提)。此外,还可以直接调用Arrays.sort()进行排序。 2.八大排序算法时间复杂度和稳定…...
SCP指令详细使用介绍
SCP(Secure Copy Protocol)是一种用于在计算机之间安全地传输文件的协议。它通过加密的方式在网络上安全地复制文件。SCP基于SSH(Secure Shell)协议,因此它提供了加密的连接和身份验证,确保数据在传输过程中…...
《前端面试题》- JS基础 - 防抖和节流
在界面触发点击,滚动,输入校验等事件时,如果对事件的触发频率不加以限制,会给浏览器增加负担,且对用户不友好。防抖和节流就是针对类似情况的解决方案。 防抖 防抖(debounce):当连续触发事件时࿰…...
RAGFlow:基于OCR和文档解析的下一代 RAG 引擎
一、引言 在人工智能的浪潮中,检索增强生成(Retrieval-Augmented Generation,简称RAG)技术以其独特的优势成为了研究和应用的热点。RAG技术通过结合大型语言模型(LLMs)的强大生成能力和高效的信息检索系统…...
正则表达式|*+?
在理解编程语言和编译技术的上下文中,了解正则表达式(regular expressions)和正则集(regular sets)的概念是非常重要的。这些概念主要用于描述一组字符串的模式,广泛应用于词法分析中识别各类标记ÿ…...
前端开发攻略---根据音频节奏实时绘制不断变化的波形图。深入剖析如何通过代码实现音频数据的可视化。
1、演示 2、代码分析 逐行解析 JavaScript 代码块: const audioEle document.querySelector(audio) const cvs document.querySelector(canvas) const ctx cvs.getContext(2d)这几行代码首先获取了 <audio> 和 <canvas> 元素的引用,并使用…...
【计算机毕业设计】基于Java+SSM的实战开发项目150套(附源码+演示视频+LW)
大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 🧡今天给大家分享150的Java毕业设计,基于ssm框架,这些项目都经过精心挑选,涵盖了不同的实战主题和用例,可做毕业设计和课程…...
STM32H7的MPU学习和应用示例
STM32H7的MPU学习记录 什么是MPU?MPU的三种内存类型内存映射MPU保护区域以及优先级 MPU的寄存器XN位AP位TEX、C、B、S位SRD 位SIZE 位CTRL 寄存器的各个位 示例总结 什么是MPU? MPU(Memory Protection Unit,内存保护单元…...
964: 数细胞
样例: 解法: 1.遍历矩阵 2.判断矩阵[i][j],若是未标记细胞则遍历相邻所有未标记细胞并标记,且计数 实现:遍历相邻所有未标记细胞 以DFS实现: function dfs(当前状态) {if (终止条件) {}vis[标记当前状…...
流程图步骤条
1.结构 <ul class"stepUl"> <li class"stepLi" v-for"(item, index) in stepList" :key"index"> <div class"top"> <p :class"{active: currentState > item.key}">{{ item.value }}…...
GPT知识库浅析
一、引言 上篇文章《GPT简介及应用》介绍了GPT的应用场景,里面提到GPT bot的基本使用:基于GPT训练好的数据,回答用户的问题。 但在使用过程中,如果用户的问题里面出现最新的术语,就会出现这种提示: 截至我…...
SpringMVC--SpringMVC的视图
目录 1. 总述 2. ThymeleafView视图 3. 转发视图 4. 重定向视图 5. 视图控制器view-controller 1. 总述 在SpringMVC框架中,视图(View)是一个非常重要的概念,它负责将模型数据(Model)展示给用户。简单…...
Datax,hbase与mysql数据相互同步
参考文章:datax mysql 和hbase的 相互导入 目录 0、软件版本说明 1、hbase数据同步至mysql 1.1、hbase数据 1.2、mysql数据 1.3、json脚本(hbase2mysql.json) 1.4、同步成功日志 2、mysql数据同步至hbase 1.1、hbase数据 1.2、mysql…...
ubuntu spdlog 封装成c++类使用
安装及编译方法:ubuntu spdlog 日志安装及使用_spdlog_logger_info-CSDN博客 h文件: #ifndef LOGGING_H #define LOGGING_H#include <iostream> #include <cstring> #include <sstream> #include <string> #include <memor…...
保温管有哪些网站做/google chrome官网下载
Dan Griffin本文讨论: 新的凭据提供程序体系结构 为什么弃用了基于 GINA 的身份验证 多因素 (Multi-factor) 身份验证 开发和调试凭据提供程序 本文使用了以下技术: Windows Vista、C目录 新旧两种体系结构的比较 混合凭据提供程序 要求 设计 混合凭据提供程序 混合方式的实现…...
连云港网站关键字优化如何/想做电商应该怎么入门
注:本账号为今日头条官方签约账号,严禁任何形式的商业转载。文丨火焱谈到手工木匠,或者说手工艺人,目前全网最火热的炸子鸡当属“手工耿”这位少侠了。此少侠依靠脑洞大开的设计和创意,被国内媒体盛赞为“无用发明家”…...
聊城网站建设公司/石首seo排名
")怎样用Python实现FTP自动上传请看PYTHON FTP模块的用法。怎么样通过Python实现自动添加脚本头信息的示例代码#!/usr/bin/python#title :test4.py#description :I am test script#author :python技术#date :20160902#version :0.1#…...
企业网站设计谁家做了的好/东莞海外网络推广
NanoMQ 继续保持稳步更新,0.9.0 将于 7 月初正式发布。此版本为大家带来了 2 个重要的功能更新:规则引擎和支持 QUIC 的 NanoSDK。同时还增加了离线数据缓存配置,各项性能优化和缺陷修复也在持续进行中。 轻便易用的嵌入式规则引擎 规则引擎…...
有人做几个蝎子养殖门户网站/指数函数图像及性质
今天我很烦,昨天网站有问题,上午提交,下午恢复。今天一早又没了,说是没缴费的问题,打了无数客服电话非说是我的域名有问题,哦赛,真麻烦啊。本来想再置办一个,想想真是怕了࿰…...
怎么做传奇网站/社交网络推广方法
文章目录文章参考案例描述定义modeleffects 参数介绍connect关联model和UI组件启动文件引入 model配置文章参考 https://dvajs.com/guide/introduce-class.html#reducerJavaScript异步编程:Generator与Async 案例描述 定义model 前面写过redux相关的笔记…...