网络编程套接字应用分享【Linux C/C++ 】【UDP应用 | TCP应用 | TCP线程池小项目】
目录
前提知识
1. 理解源ip,目的ip和Macip
2. 端口号
3. 初识TCP,UDP协议
4. 网络字节序
5. socket 编程
sockaddr类型
一,基于udp协议编程
1. socket——创建套接字
2. bind——将套接字强绑定
3. recvfrom——接受数据
4. sendto——发出信息
遇到的问题
(1. 云服务器中以及无法分配IP问题
(2. IP:127.0.0.1更深层次的认识
(3. 关于服务端bind的优化
源码
二,基于tcp协议编程
1. listen——服务端监听
2. accept——服务端接收
3. connect——客户端请求
4. send & recev
三,基于TCP协议实现的线程池的服务端对客户端进行相互通信小项目
结构图一览
源码
1. 单进程处理
2. 子进程处理
2.1. 孙子进程处理
3. 多线程处理
4. 线程池处理
下期:TCP协议原理
结语
嗨!收到一张超美的风景图,愿你每天都能顺心!
前提知识
1. 理解源ip,目的ip和Macip
数据在以太网上传输,经过多个路由器,Mac地址多次封装解包是变化的(可以理解为数据的下一个主机地址),而源ip,尤其是目的ip一般是不会改变。
2. 端口号
- 端口号是一个2字节16位的整数(uint16_t);
- 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理;
- 一个端口号只能被一个进程占用(标识一台主机进程的唯一性)
理解:假设客户发送操作在终端应用为A,在另一台机器的服务器应用为B,A向B发送操作请求,本质上是不同机器之间进程间通信,请求数据经过封装,传递,解包后,B所在的操作系统将数据根据端口号,交给那个进程处理。
同理,我们就能理解源端口号,就是发出数据的进程;目的端口号,处理数据的进程 。
因此,IP地址 + 端口号能够标识网络上的唯一台主机的唯一一个进程;
注意:
1.一个进程可以有多个端口号绑定,但一个端口不能被多个进程绑定。
2. pid是系统管理进程的唯一标识符,与端口号没有联系。
同时,{IP地址 + 端口号}的模式被叫做套接字,网络通信用套接字的方法实现,网络编程,也可以被叫做套接字编程。
3. 初识TCP,UDP协议
首先我们来找找他们传输层上的这两协议
这里我们只了解两协议的特点,具体我们后面再结合场景理解
各自特点:
TCP(Transmission Control Protocol 传输控制协议)
- 传输层协议
- 有连接(是否需要手动连接)——神似打电话
- 可靠传输(对数据包检测,丢包重传等等)
- 面向字节流(后面再提)
UDP(User Datagram Protocol 用户数据报协议)
- 传输层协议
- 无连接(不用连接就可以发送)——神似发邮件
- 不可靠传输(不关心是否丢包)
- 面向数据报(后面再说)
4. 网络字节序
说到字节序,我们是否想到C语言中学过的大小端字节序,那个是数据在内存中的存储方式。(大小端可参见:整型,浮点型深刻理解【C语言】【整型 || 原,反,补码 || 浮点型 || 大小端字节序】_小端浮点数-CSDN博客)
现在我们讨论的则是数据在向网络发送时,是从低字节向高地址发送(小端),还是从高字节向高地址发送(大端)。
- 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
- 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
- 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
- TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.
- 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据;
- 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可
意思是:以htonl()为例,主机字节转网络字节序,返回数据。
5. socket 编程
首先我们先简单了解常用的三中套接字:
- 域用socket (基于网络socket下的本地模式,类似于命名管道,可参见:进程通信知识基础【Linux】——下篇【命名管道,共享内存,信号量初识】-CSDN博客
- 原始socket (一般用于一些工具制作——跳过传输层协议直接用于网络层,甚至数据链路层)
- 网络socket
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address, socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockaddr类型
一,基于udp协议编程
1. socket——创建套接字
返回值:文件描述符作为返回值
domain: 设置套接字类型(网络通信,还是本地通信)
protocol: 一般根据前两参数就决定好了,设置为0即可。
2. bind——将套接字强绑定
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
需要区别C++11中std::bind,后者是C++11的包装器,用于函数参数管理。这里的是三种socket通信绑定套接字的通用接口,下面是实例:
sockaddr_in结构体头文件<netinet/in.h>
// 2.让操作系统将该进程与我们的套接字进行强绑定,以便内核中我们信息的获取struct sockaddr_in local;// 全0填充,可以用memset,bzerobzero(&local, sizeof bzero);local.sin_family = AF_INET; // 设置通信类型// 服务器的ID和端口未来是要将数据发送到网络中,数据就需要修改为大端。local.sin_port = htons(_port); // 对IP地址补充:// 常见的是"192.234.222.111"——点分十进制字符串风格的IP地址,目的:用户方便观察// 分成四个领域,每个领域都是[0~255],也就是2^8,1字节,所以IP,4字节可以完全表示// 如果网络以上面字符串形式传输就是15字节,所以需要15字节 <-> 4字节(网络)local.sin_addr.s_addr = inet_addr(_id.c_str()); //4字节的ID也需要修改if (bind(socket_, (sockaddr*)&local, sizeof local) < 0){Logmessage(FATIL, "%d:%s\n", errno, strerror(errno));}
如果绑定成功,接下来主机就从可以从该套接字中接收数据。
常见的网络转换数据接口,具体用法问AI
man inet_addr
3. recvfrom——接受数据
参数解析:
- sockfd: 创建完的套接字返回文件标识符——还是遵从一切为文件
- buf, len :信息缓冲区
- flags : 默认为0,为阻塞方式接受信息
- src_addr, addrlen :一个输出型参数,收集发送者套接字(IP + 端口)。
- return : 返回发送者发送字节数。
- sockaddr*, socklen_t* :两类型是输出式参数,用于记录发送方套接字
4. sendto——发出信息
需要注意的是socklen_t类型,需要
使用例子请看下面:
功能:一个客户端,一个服务器,在同一台机器上通过IP:127.0.0.1来实现互相数据发送。
//服务器启动int start(){char buf[1024];while (1){//1.接受信息struct sockaddr_in peer;bzero(&peer, sizeof peer);socklen_t len = sizeof peer;ssize_t s_len = recvfrom(socket_, buf, (sizeof buf) - 1, 0, (struct sockaddr*)&peer, &len);if (s_len > 0){buf[s_len] = 0; // 协议分析,这里我们先不说//解析发送目标uint16_t send_port = ntohs(peer.sin_port);std::string send_id = inet_ntoa(peer.sin_addr);printf("发送方 id:[%s] port:[%d]:%s\n",send_id.c_str(), send_port, buf);}//2.分析信息 //3.发出信息,我们选择发送回sendto(socket_, buf, sizeof buf, 0, (struct sockaddr*)&peer, len);} }
(详细代码链接,我将放到文章末尾)
遇到的问题
(1. 云服务器中以及无法分配IP问题
答:我们使用云服务器进行代码学习时,自己无法分配除127.0.0.1的IP,即使是自己的云服务器IP,因为是供应商提供的虚拟IP,所以云服务器就不允许分配其他IP。
(2. IP:127.0.0.1更深层次的认识
答:为什么可以使用127.0.0.1 IP,因为这是一个本地环回的IP,在这个IP下数据经过本地协议栈后不会进入网络,而是直接从栈底回到操作系统,同时这也是适合本地网络服务测试,如果接入网络通信,没有接通则大概率是网络的原因。
(3. 关于服务端bind的优化
答:首先我们完善一下从上面代码对bind的认识
修改方法:在添加IP地址时,将IP修改为任意IP即可。
宏 : INADDR_ANY 本质上就是0
关于在Windows下使用客户端
上面创建的客户端都是linux下的客户端,如果我们想在Windows下使用, -phread这个第三方库就用不了,而客户端就要更改源码库,使用window的网络套接字接口,但好在几乎类似,最后在VS本地运行即可。
自己实现的类一定要进行备注使用方法,返回值类型,以免代码复用时,出现返回值类型问题!!(别问我为啥要单独写一行,因为在转类型时,转错了,一直段错误,人都傻了,结果后面发现,原来是自己实现类的用法忘记了,害,一个早上的教训啊)
源码
下面的源码介绍:cline端:基于多线程将送,收消息分离; service端:不绑定特定IP,实现接收,并回发消息。
udb_socket简单聊天室源码:NetworkProgramming · 逆光/Linux - 码云 - 开源中国 (gitee.com)
二,基于tcp协议编程
1. listen——服务端监听
功能:listen接口是用于创建一个被动的套接字,用于监听传入的连接请求的接口。当一个套接字调用listen接口后,它将开始接受传入的连接请求,并将这些请求排队,等待被接受或拒绝。(就像一个饭店的外面的拉客人)
sockfd:监听用的套接字
backlog: 指定在拒绝新连接之前,操作系统可以排队等待的最大连接数量。
返回值:0成功,-1失败。
2. accept——服务端接收
功能:accept()函数会在sockfd套接字上接受一个传入的连接请求(阻塞式接收),并返回一个新的套接字描述符,用于和客户端进行通信。同时,addr和addrlen参数会被填充上客户端的地址信息。
//1. 接受请求struct sockaddr_in send_; //请求方信息bzero(&send_, sizeof send_);socklen_t len = sizeof send_;// accept会等待请求方申请,会处于阻塞状态int actual_socket = accept(listen_socket_, (sockaddr*)&send_, &len);if ( actual_socket < 0 ){Logmessage(FATIL, "accept fail%d %s", errno, strerror(errno));continue;}
3. connect——客户端请求
在调用 connect() 函数后,系统会尝试连接到指定的服务器地址。(多客户端向服务端进行连接)
成功,返回值为0;如果连接失败,返回值为-1,并且可以通过 errno 变量获取具体的错误信息。
// 1.保留目标信息struct sockaddr_in goal_service;bzero(&goal_service, sizeof goal_service);goal_service.sin_family = AF_INET;goal_service.sin_port = htons(atoi(args[2]));goal_service.sin_addr.s_addr = inet_addr(args[1]);// 2.建立连接if (connect(cline_socket, (sockaddr*)&goal_service, sizeof goal_service) < 0){Logmessage(FATIL, "cline connect fail %d %s", errno, strerror(errno));exit(1);}
4. send & recev
功能: send()函数将数据从buf缓冲区发送到已连接的套接字或者未连接的套接字(后者的UDP多用sendto)
- sockfd:要发送数据的套接字描述符。
- flags:传递给send()函数的标志参数,通常为0
- 返回值:成功,返回字节数;失败,-1
功能:recv()函数会阻塞程序,直到接收到足够的数据或发生错误。
sockfd:指定要接收数据的套接字描述符。
flags:指定接收数据的附加选项,通常为0。
返回值:成功,字节数;0,连接关闭;异常,-1。
三,基于TCP协议实现的线程池的服务端对客户端进行相互通信小项目
结构图一览
我的体会,客户端以及服务端的设计,在UDP设计中基本已经写过了,TCP只是有一些小改动;然后就是线程池也是直接使用了,前面我们所写的线程池小项目,总体来说考验我们的代码整合能力吧。
源码
线程池小项目:Tcp_NetworkProgramming · 逆光/Linux - 码云 - 开源中国 (gitee.com)
有人会说,万一我不想用线程池来实现服务端处理客户端的请求呢?而是使用一些比较小型的呢?答:有,而且不止几种
首先我们为什么要用线程池这个结构?
答: 服务端不能一次只接受一个客户端的请求,所以需要其他结构(子进程或多线程)来满足客户端的服务,主线程只要接收请求,分配任务即可。
服务端处理客户端请求方法——由简到密
1. 单进程处理
void start(){signal(SIGCHLD, SIG_IGN);//循环接受信息while (1){//1. 接受请求struct sockaddr_in send_; //请求方信息bzero(&send_, sizeof send_);socklen_t len = sizeof send_;// accept会等待请求方申请,会处于阻塞状态int actual_socket = accept(listen_socket_, (sockaddr*)&send_, &len);if ( actual_socket < 0 ){Logmessage(FATIL, "accept fail%d %s", errno, strerror(errno));continue;}// 连接成功std::string send_ip = inet_ntoa(send_.sin_addr);uint16_t send_port = ntohs(send_.sin_port);Logmessage(NOWAIN, "连接成功,客户端为 ip:%s 端口号:%d", send_ip.c_str(), send_port);// (1.0)服务器处理信息——单进程版本// //2. 分析处理数据server_dispose(actual_socket, send_ip, send_port);
缺点:无法满足服务器多客户端连接
2. 子进程处理
// 连接成功std::string send_ip = inet_ntoa(send_.sin_addr);uint16_t send_port = ntohs(send_.sin_port);Logmessage(NOWAIN, "连接成功,客户端为 ip:%s 端口号:%d", send_ip.c_str(), send_port);// (2.0) 优化——子进程版本pid_t pd = fork();if (pd == 0){//2. 分析处理数据close(listen_socket_); //子进程拷贝一份父进程的文件描述服表server_dispose(actual_socket, send_ip, send_port);exit(0);}close(actual_socket); // 子进程里保留了该文件描述符,父进程已经不需要了// 按照曾经的理解,现在应该让父进程进行等待子进程,但多少都存在些问题。// 1. waitpid阻塞式等待,不就跟单线程一样?// 2. 非阻塞式等待,需要构建子进程管理结构比较麻烦,而且我们不需要关心子进程的返回情况。// 因此我们可以采用信号知识,忽略子进程返回。// 操作细则:在service启动时 signal(SIGCHLD, SIG_IGN);
2.1. 孙子进程处理
// 连接成功std::string send_ip = inet_ntoa(send_.sin_addr);uint16_t send_port = ntohs(send_.sin_port);Logmessage(NOWAIN, "连接成功,客户端为 ip:%s 端口号:%d", send_ip.c_str(), send_port);// (2.1) ———— 子进程退出,孙子进程让1接管pid_t pd = fork();if (pd == 0){//2. 分析处理数据close(listen_socket_); //子进程拷贝一份父进程的文件描述服表if (fork() > 0) exit(0); // 孙子进程变成孤儿进程,让bash接管server_dispose(actual_socket, send_ip, send_port);exit(0);}waitpid(pd, nullptr, 0); // 子进程进入立马退出,父进程几乎不阻塞等待
缺点:虽然满足了服务端可以同时满足多个客户端连接,但是进程的创建会比较大的开销 。
3. 多线程处理
static void* pth_service(void* args){PthreadData* data = static_cast<PthreadData*>(args);// 进来先剥离线程,这样主线程不用等待返回pthread_detach(pthread_self());server_dispose(data->_actual_socket, data->_ip, data->_port);close(data->_actual_socket);delete data;return nullptr;}..........// 连接成功std::string send_ip = inet_ntoa(send_.sin_addr);uint16_t send_port = ntohs(send_.sin_port);Logmessage(NOWAIN, "连接成功,客户端为 ip:%s 端口号:%d", send_ip.c_str(), send_port);// (3.0) ———— 多线程版本pthread_t it = -1; // 线程的标识号先默认为1,后面在设置。PthreadData* data = new PthreadData;data->_ip = send_ip;data->_port = send_port;data->_actual_socket = actual_socket;pthread_create(&it, nullptr, pth_service, (void*)data);
缺点:1. 没有设置最大线程数,在高压情况下有可能会导致service服务崩溃。2. 短时间内大量请求,线程开辟消耗比较大的资源。
4. 线程池处理
// 连接成功std::string send_ip = inet_ntoa(send_.sin_addr);uint16_t send_port = ntohs(send_.sin_port);Logmessage(NOWAIN, "连接成功,客户端为 ip:%s 端口号:%d", send_ip.c_str(), send_port);// (4.0) ———— 启用线程池// 让线程来进行对网络端的信息进行处理Task_add* task = new Task_add(actual_socket, send_port, send_ip);_thr_pool->push(task);// 交换策略:服务端未被占满时,来一条就交换任务队列if (_thr_pool->Get_queue_task_size() == 0 && _thr_pool->Get_queue_task_reserver_size() != 0){_thr_pool->swap_queue();}
功能基本上没什么问题了,但我们在客户端处理逻辑上是循环,意味着该线程不会退出,也就是长连接。意味着,客户端的最大连接数就是线程池的数量,如果客户端逻辑是短连接,就不会出现线程池一直占满的情况了。
以上的编程是我们在应用层使用的编码,往后我们将向下深入理解网络理解。
下期:TCP协议原理
结语
本小节就到这里了,感谢小伙伴的浏览,如果有什么建议,欢迎在评论区评论,如果给小伙伴带来一些收获请留下你的小赞,你的点赞和关注将会成为博主创作的动力
相关文章:
网络编程套接字应用分享【Linux C/C++ 】【UDP应用 | TCP应用 | TCP线程池小项目】
目录 前提知识 1. 理解源ip,目的ip和Macip 2. 端口号 3. 初识TCP,UDP协议 4. 网络字节序 5. socket 编程 sockaddr类型 一,基于udp协议编程 1. socket——创建套接字 2. bind——将套接字强绑定 3. recvfrom——接受数据 4. s…...
有关数据开发项目中使用HIVE由于无法update和delete的场景下,如何解决数据增量的思路
解决数据增量问题的思路在Hive中 在数据开发项目中,使用Hive进行数据处理时,由于Hive不支持update和delete语句,处理数据增量可能会变得有些棘手。然而,有几种策略和技术可以帮助我们解决这个问题,并确保数据增量的高…...
两数之和-考察哈希表的运用
题目 给定一个整数数组 n u m s nums nums和一个整数目标值 t a r g e t target target,请你在该数组中找出和为目标值 t a r g e t target target的那 两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同…...
视觉检测系统,外观细节无可挑剔
在传统行业中,利用人工检测来检测产品外观缺陷依然是主流,但由于竞争的加剧,对企业生产效率的要求也越来越高。传统的检测产品外观缺陷问题的方法就是透过人工目检,或者工人采用游标卡尺等工具检测,此种方式检测速度慢…...
C++中string容器的字符串操作
目录 1.c_str() 返回C常量字符串 2.date() 返回C常量字符串 3.substr() 构造子串 4.find() 正向查找(查找失败返回npos) 5.rfind() 逆向查找(查找失败返回npos) 6.find_first_of() 正向查找匹配的字符 7.find_last_of() 逆向…...
Java编程使用CGLIB动态代理介绍与实战演示
文章目录 前言技术积累核心概念主要功能适用场景与JDK动态代理的对比 实战演示定义待代理的目标类实现MethodInterceptor接口使用代理对象 测试结果写在最后 前言 在Java编程中,CGLIB (Code Generation Library) 是一个强大的高性能代码生成库,它通过生…...
vue3 渲染一个后端返回的图片字段渲染、table表格内放置图片
一、后端直接返回图片url 当图片字段接口直接返回的是图片url,可以直接放到img标签上 <img v-if"thumbLoader" class"r-image-loader-thumb" :src"resUrl" /> 二、当图片字段接口直接返回的是图片Id 那么就需要去拼一下图片…...
iOS开发进阶(十三):脚手架创建iOS项目
文章目录 一、前言二、xcode-select 命令三、拓展阅读 一、前言 项目初期,需要搭建项目基本框架,为此离不开辅助工具,即脚手架。当然,IDE也可以实现新建空白项目,但是其新建后的项目结构可能不符合预期设计࿰…...
手机无线投屏到windows11电脑
1 安装无线投影组件 2 电脑端打开允许其他设备投影的开关 3 手机找到投屏选项 4 手机搜索可用设备连接即可 这里的官方文档给的不太好,给了一些让人眼花撩乱的信息,以下是经过整合的有效信息...
linux 环境安装配置
安装java17 1.下载安装包 wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz 2.解压到自定义目录/usr/local/java mkdir /usr/local/java tar zxvf jdk-17_linux-x64_bin.tar.gz -C /usr/local/java 3.配置环境变量 echo export PATH$PATH:/…...
Git常用语句
设置用户名 git config --global user.name "用户名" git config --global user.email "邮箱"查看git用户信息 cat ~/.gitconfig初始化本地库 git initclone指定分支的代码 git clone -b my_branch gitgitlabxxxxxxxxxxxxxxxxxxxxxx.gitpush三件套 gi…...
坦克大战_java源码_swing界面_带毕业论文
一. 演示视频 坦克大战_java源码_swing界面_带毕业论文 二. 实现步骤 完整项目获取 https://githubs.xyz/y22.html 部分截图 启动类是 TankClinet.java,内置碰撞检测算法,线程,安全集合,一切皆对象思想等,是java进阶…...
JVM 记录
记录 工具 https://gceasy.io 资料 尚硅谷宋红康JVM全套教程(详解java虚拟机) https://www.bilibili.com/video/BV1PJ411n7xZ?p361 全套课程分为《内存与垃圾回收篇》《字节码与类的加载篇》《性能监控与调优篇》三个篇章。 上篇《内存与垃圾回收篇…...
Linux学习笔记————C 语言版 LED 灯实验
这里写目录标题 一、实验程序编写二、 汇编部分实验程序编写三、C 语言部分实验程序编写四、编译下载验证 汇编 LED 灯实验中,我们讲解了如何使用汇编来编写 LED 灯驱动,实际工作中是很少用到汇编去写嵌入式驱动的,毕竟汇编太难,而…...
Spring Boot 配置文件
1. 配置文件的作用 配置文件主要是为了解决硬件编码带来的问题,把可能会发生改变的信息,放在一个集中的地方,当我们启动某个程序时,程序从配置文件中读取一些数据,并加载运行。 硬编码是将数据直接放在源代码中&…...
IPKISS ------ 查看器件默认端口名称
IPKISS ------ 查看器件默认端口名称 正文正文 我们这里以 Grating Coupler 举例。 import si_fab.all as pdk import ipkiss3.all as i3class MyGratingCoupler(i3.circuit):gc = i3.childcellProperty(<...
uni-app踩坑记录
uni-app踩坑记录 Failed to load local image resource xxx the server responded with a status of 500 (HTTP/1.1 500 Internal Server Error) Failed to load local image resource xxx the server responded with a status of 500 (HTTP/1.1 500 Internal Server Error) 文…...
【嵌入式硬件】光耦
1.光耦作用 光耦一般用于信号的隔离。当两个电路的电源参考点不相关时,使用光耦可以保证在两边不共地的情况下,完成信号的传输。 2.光耦原理 光耦的原理图如下所示,其内部可以看做一个特殊的“三极管”; 一般的三极管是通过基极B和发射极E间的电流,去控制集电极C和发射极…...
学习Fast-LIO系列代码中相关概念理解
目录 一、流形和流形空间(姿态) 1.1 定义 1.2 为什么要有流形? 1.3 流形要满足什么性质? (1) 拓扑同胚 (2) 可微结构 1.4 欧式空间和流形空间的区别和联系? (1) 区别: (2) 联系: 1.5 将姿态定义在流形上比…...
React 掌握及对比常用的8个Hooks,优化及使用场景
1、useState 在函数组件中,可以使用useState来定义函数组件的状态。使用useState来创建状态。 1.引入2.接收一个参数作为初始值3.返回一个数组,第一个值为状态,第二个值为改变状态的函数 2、 useEffect useEffect又称副作用hooks。作用&…...
DNS域名解析过程
在互联网中我们通信目标是对方的IP,但是由于IP不便于记忆所以引入了域名 域名和IP是一一对应的关系,需要注意的是域名和网址是不同的概念 比如:www.csdn.net是域名,https://www.csdn.net/?spm1001.2101.3001.4476是网址 首先了解…...
MySQL数据库(数据库连接池)
文章目录 1.批处理应用1.基本介绍2.批处理演示1.创建测试表2.修改url3.编写java代码 3.批处理源码分析 2.数据库连接池1.传统连接弊端分析2.数据库连接池基本介绍1.概念介绍2.数据库连接池示意图3.数据库连接池种类 3.C3P0连接池1.环境配置1.导入jar包2.将整个lib添加到项目中3…...
【C#】知识点速通
前言: 笔者是跟着哔站课程(Trigger)学习unity才去学习的C#,并且C语言功底尚存,所以只是简单地跟着课程将unity所用的C#语言的关键部分进行了了解,然后在后期unity学习过程中加以深度学习。如需完善的C#知识…...
FTP协议
FTP协议 客户端向服务器发送文件。 C/S架构。 运行在TCP/IP协议上面。 FTP客户端要和FTP服务端建立两个TCP连接。 控制连接:运行在整个连接过程,传输控制信息。 数据连接:在每次文件传输时才会建立,文件传输完就关闭。 主动模式…...
前后端分离开发【Yapi平台】【Swagger注解自动生成接口文档平台】
前后端分离开发 介绍开发流程Yapi(api接口文档编写平台)介绍 Swagger使用方式1). 导入knife4j的maven坐标2). 导入knife4j相关配置类3). 设置静态资源映射4). 在LoginCheckFilter中设置不需要处理的请求路径 查看接口文档常用注解注解介绍 当前项目中&am…...
Android的硬件接口HAL-2 HIDL
没写完哈。 不说废话,直接上干活。 1 创建HAL mkdir -p vendor/fanged/hidltest/1.0/defaultvi vendor/fanged/hidltest/1.0/Ilovefanged.hal package vendor.fanged.hardware.hidltest1.0;interface Ilovefanged {add(int32_t a, int32_t b) generates (int32_t…...
pygame--坦克大战(二)
加载敌方坦克 敌方坦克的方向是随机的,使用随机数生成。 初始化敌方坦克。 class EnemyTank(Tank):def __init__(self,left,top,speed):self.images = {U: pygame.image.load(img/enemy1U.gif),D: pygame.image.load(img/enemy1D.gif),L: pygame.image.load(img/enemy1L.gi…...
【C语言】标准输入/输出(printf, scanf, gets, puts, getchar, putchar)
标准文件文件指针设备标准输入stdin键盘标准输出stdout屏幕标准错误stderr您的屏幕 标准输入/输出的函数在标准库stdio.h。 #include <stdio.h> 1、printf 输出 printf :格式化输出,输出到标准输出stdout中。 printf: int print…...
C、C++、C#中.vscode下json文件记录
C launch.json {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid830387"version": "0.2.0","configurations": [{"name": &quo…...
2013年认证杯SPSSPRO杯数学建模B题(第二阶段)流行音乐发展简史全过程文档及程序
2013年认证杯SPSSPRO杯数学建模 B题 流行音乐发展简史 原题再现: 随着互联网的发展,流行音乐的主要传播媒介从传统的电台和唱片逐渐过渡到网络下载和网络电台等。网络电台需要根据收听者的已知喜好,自动推荐并播放其它音乐。由于每个人喜好…...
做网站字体要求/网站推广计划
01 代码下载 和 chromium 配置完全一致,只是 fetch 参数指定为 webrtc 本次编译采用 4664 分支(版本号96) fetch --no-history webrtc cd src #git checkout -b b4664 remotes/branch-heads/4664 # 4664 可以编译过,没跑起来 git checkout -b b4515 re…...
西宁 网站建设/seo是什么姓氏
本节书摘来自异步社区《Spring攻略(第2版)》一书中的第1章,第1.11节,作者: 【美】Gary Mak , Josh Long , Daniel Rubio著,更多章节内容可以访问云栖社区“异步社区”公众号查看 1.11 用XML配置自动装配Be…...
商业营销厅装修公司/seo快速排名代理
使用 gensim 训练中文词向量,计算词语之间的相似度。 输入:语料库,txt文件。 输出:余弦相似度。 实现代码: # -*- coding: utf-8 -*-import loggingfrom gensim import models from gensim.models import word2vec…...
网站变成灰色/免费的网站推广软件下载
以前用ASP.net做web网站时用的都是sqlserver 数据库,也没有了解用mysql如何连接,遂今天试了下,多余就不说了,直接上步骤了。首先我采用的是MySql.Data.dll这种方式连接数据库,我把放在百度云上了,大家可以下…...
网站建设硬件和软件技术环境配置/百度品牌广告是什么
dispatchTouchEvent事件派发显示隧道方式、再是冒泡方式隧道方式传递,直道某一个元素消耗此事件,由上至下逐层分发视图。冒泡方式传递,当某个视图消耗事件后其return boolean 是与分发相反的方法向上传递。具体分发给哪一个视图是通过当前触摸…...
做网站的都改行做什么了/友情链接名词解释
关于函数传值 this.getPurchaseHistoryData(index, num,timeType);第一位是显示的页数,第二是控制首页4上一页-1下一页是2末页是5 第三是是对昨天是1,今天是2,还是一段时间的控制传3,默认是0 1.关于分页:(…...