IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 遥控小车(基于TCP/IP) -> 正文阅读

[网络协议]遥控小车(基于TCP/IP)

? ? ? ? 其实我更想用32的板子来完成这个项目,但是老师要求只能用GEC6818的板子,虽然这个板子功能更加全面,但本人还是对32熟悉一些,所以前期还是花了很多时间来研究这块板子,总的来说其实步骤还是差不多的。实现代码在文章最底下。

1、总体设计任务框图

?

2、设计任务:

本设计是基于粤嵌gec6818开发板完成远端操控小车的操作,小车需要纯手工组装。

要求:

完成各模块功能的构建,使用QT的界面设计和安卓配置作为客户端给服务器端发送数据,在服务器端接收数据并创建子线程处理数据。通过看6818底板电路图发现可使用GPIO_C7、C8、C17和GPIO_E13输出电平给电机供电,并且可通过调节占空比来控制小车速度。

3、功能要求及技术指标

  1. 完成各模块功能的构建,要求掌握客户端相关功能的构建,要求掌握驱动相关功能的构建,要求掌握服务器端相关功能的构建。
  2. 完成各模块程序设计与编写要求掌握TCP网络编程的基本功能和作用,要求掌握驱动控制实现电机转动,要求掌握基于QT5和Android的界面设计。
  3. 完成各项性能测试,要求实现客户端与服务器端的连接,要求实现电机驱动及速度控制,要求实现按钮控制小车。
  4. 完成最终应用程序功能的组合,要求通过TCP网络编程、QT和Android界面设计和驱动编译组合实现控制小车跑。

4、 总体设计方案

????????运用QT实现基本的TCP客户端和服务器端的基本通信,客户端实现与服务器端建立连接、发送数据与断开,服务器端接收客户端数据并创建子线程来处理接收到的数据。再通过UI和安卓界面设计来实现按钮控制小车,再通过给四个GPIO口输出高低电平来控制电机转动和速度,最后实现控制小车。

5 系统测试

客户端:QT版与安卓版

(ps:奥迪rs7是不是你的终极梦想,哈哈哈)

?

?

服务器端:基于粤嵌6818的智能小车

6 使用说明

????????当你在输入框内输入正确的IP地址以及端口号,点击链接即可成功并在显示窗口显示连接成功,然后就可以通过点击前进,后退,左转,右转,停止来实现控制小车运动,点击断开及失去控制权。

7.附录代码

服务器端:

int port = 6666;

// GPIOC7的编号为: PAD_GPIO_C + 7

enum {

????PAD_GPIO_A ?????= (0 * 32),

????PAD_GPIO_B ?????= (1 * 32),

????PAD_GPIO_C ?????= (2 * 32),

????PAD_GPIO_D ?????= (3 * 32),

????PAD_GPIO_E ?????= (4 * 32),

????PAD_GPIO_ALV ???= (5 * 32),

};

//GPIO模式

#define GPIO_MODE_INPUT ?1

#define GPIO_MODE_OUTPUT ?0

#define THREAD_NUMBER ??????1 ?

typedef struct gpio_cfg_t

{

unsigned int gpio_no; //gpio的编号

unsigned int gpio_mode; // input/output

unsigned int init_value; // 当gpio配置成output模式时

?//指定输出的初始值。

}gpio_cfg_t;

typedef struct gpio_value

{

unsigned int gpio_no; //gpio的编号

unsigned int gpio_value;

} gpio_value_t;

#define GPIO_CONFIG ?_IOW('G', 1, gpio_cfg_t)

#define GPIO_SET_VALUE _IOW('G', 2, gpio_value_t)

#define GPIO_GET_VALUE _IOWR('G', 3, gpio_value_t)

gpio_cfg_t gpio_init;

gpio_value_t gpio_clear;

void GPIO_Init(int fd)

{

gpio_init.gpio_no = PAD_GPIO_C + 7;

gpio_init.gpio_mode = GPIO_MODE_OUTPUT; //输出模式

gpio_init.init_value = 0; //初始输出 低电平 

ioctl(fd, GPIO_CONFIG, &gpio_init);

gpio_init.gpio_no = ?PAD_GPIO_C + 8;

????????gpio_init.gpio_mode = GPIO_MODE_OUTPUT; //输出模式

????????gpio_init.init_value = 0; //初始输出 低电平 

????????ioctl(fd, GPIO_CONFIG, &gpio_init);

????????gpio_init.gpio_no = ?PAD_GPIO_C + 17;

????????gpio_init.gpio_mode = GPIO_MODE_OUTPUT; //输出模式

????????gpio_init.init_value = 0; //初始输出 低电平 

????????ioctl(fd, GPIO_CONFIG, &gpio_init);

????????gpio_init.gpio_no = ?PAD_GPIO_E + 13 ;

????????gpio_init.gpio_mode = GPIO_MODE_OUTPUT; //输出模式

????????gpio_init.init_value = 0; //初始输出 低电平 

????????ioctl(fd, GPIO_CONFIG, &gpio_init);

}

void clear(int fd)

{

gpio_clear.gpio_no = PAD_GPIO_C + 7;

gpio_clear.gpio_value = 0;

ioctl(fd, GPIO_SET_VALUE, &gpio_clear);

????????gpio_clear.gpio_no = PAD_GPIO_C + 8;

????????gpio_clear.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_clear);

????????gpio_clear.gpio_no = PAD_GPIO_C + 17;

????????gpio_clear.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_clear);

????????gpio_clear.gpio_no = ?PAD_GPIO_E + 13;

????????gpio_clear.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_clear);

}

void forward(int fd)

{

gpio_value_t gpio_value_1;

gpio_value_1.gpio_no = PAD_GPIO_C + 7;

gpio_value_1.gpio_value = 1;

ioctl(fd, GPIO_SET_VALUE, &gpio_value_1);

????????gpio_value_t gpio_value_2;

????????gpio_value_2.gpio_no = PAD_GPIO_E + 13;

????????gpio_value_2.gpio_value = 1;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_2);

?gpio_value_t gpio_value_C8;

????????gpio_value_C8.gpio_no = PAD_GPIO_C + 8;

????????gpio_value_C8.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C8);

????????gpio_value_t gpio_value_C17;

????????gpio_value_C17.gpio_no = PAD_GPIO_C + 17;

????????gpio_value_C17.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C17);

}

void back(int fd)

{

gpio_value_t gpio_value_3;

????????gpio_value_3.gpio_no = PAD_GPIO_C + 8;

????????gpio_value_3.gpio_value = 1;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_3);

????????gpio_value_t gpio_value_4;

????????gpio_value_4.gpio_no = PAD_GPIO_C + 17;

????????gpio_value_4.gpio_value = 1;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_4);

????????gpio_value_t gpio_value_C7;

????????gpio_value_C7.gpio_no = PAD_GPIO_C + 7;

????????gpio_value_C7.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C7);

????????gpio_value_t gpio_value_E13;

????????gpio_value_E13.gpio_no = PAD_GPIO_E + 13;

????????gpio_value_E13.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_E13);

}

void turn_left(int fd)

{

gpio_value_t gpio_value_5;

gpio_value_5.gpio_no = PAD_GPIO_C + 7;

gpio_value_5.gpio_value = 1;

ioctl(fd, GPIO_SET_VALUE, &gpio_value_5);

????????gpio_value_t gpio_value_6;

????????gpio_value_6.gpio_no = PAD_GPIO_C + 8;

????????gpio_value_6.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_6);

????????gpio_value_t gpio_value_C17;

????????gpio_value_C17.gpio_no = PAD_GPIO_C + 17;

????????gpio_value_C17.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C17);

????????gpio_value_t gpio_value_E13;

????????gpio_value_E13.gpio_no = PAD_GPIO_E + 13;

????????gpio_value_E13.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_E13);

// sleep(1);

// forward(fd);

}

void turn_right(int fd)

{

gpio_value_t gpio_value_7;

gpio_value_7.gpio_no = PAD_GPIO_C + 17;

gpio_value_7.gpio_value = 1;

ioctl(fd, GPIO_SET_VALUE, &gpio_value_7);

????????gpio_value_t gpio_value_8;

????????gpio_value_8.gpio_no = PAD_GPIO_E + 13;

????????gpio_value_8.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_8);

????????gpio_value_t gpio_value_C7;

????????gpio_value_C7.gpio_no = PAD_GPIO_C + 7;

????????gpio_value_C7.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C7);

????????gpio_value_t gpio_value_C8;

????????gpio_value_C8.gpio_no = PAD_GPIO_C + 8;

????????gpio_value_C8.gpio_value = 0;

????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C8);

// sleep(1);

// forward(fd);

}

/*处理接收客户端消息函数*/

int ret;

void *recv_message(void *fd)

{

int sockfd = *(int *)fd;

int i,j,k,n;

????????printf("received from client:%d\n", ret);

while(1)

{

??

switch(ret)

{

case 0:clear(sockfd);break;

case 1:

????????for(i = 0;i < 10;i++)

?????? ??{

???????????????? if(i == 0 | i == 4 | i == 7)

??????????????? ?{

???????????????????????? forward(sockfd);

???????????????? }

??????????????? ?else

??????????????? ?{

???????????????????????? clear(sockfd);

??????????????? ?}

??????? ?}

// forward(sockfd);

break;

case 2:

????????????????for(j = 0;j < 10;j++)

??????????????????{

????????????????????????if(j == 0 | j == 4 | j == 7)

?????????????????????????{

????????????????????????????????back(sockfd);

????????????????????????}

?????????????????????????else

?????????????????????????{

????????????????????????????????clear(sockfd);

?????????????????????????}

?????????????????}

// back(sockfd);

break;

case 3:

????????????????for(k = 0;k < 10;k++)

??????????????????{

????????????????????????if(k == 0 |k == 4 |k ==7)

?????????????????????????{

????????????????????????????????turn_left(sockfd);

????????????????????????}

?????????????????????????else

?????????????????????????{

????????????????????????????????clear(sockfd);

?????????????????????????}

?????????????????}

// turn_left(sockfd);

break;

case 4:

????????????????for(n = 0;n < 10;n++)

??????????????????{

????????????????????????if(n == 0 | n == 4 | n == 7)

?????????????????????????{

????????????????????????????????turn_right(sockfd);

????????????????????????}

?????????????????????????else

?????????????????????????{

????????????????????????????????clear(sockfd);

?????????????????????????}

?????????????????}

// turn_right(sockfd);

break;

default:printf("recivice error");break;

}

}//while

}

int main()

{

?????int fd = open("/dev/gec6818_gpios", O_RDWR);

?????if (fd == -1)

?????{

?????????????perror("failed to open:");

?????????????return -1;

?????}

//声明套接字

int listenfd , connfd;

socklen_t clilen;

//声明线程ID

pthread_t recv_tid , send_tid;

//定义地址结构

struct sockaddr_in servaddr , cliaddr;

GPIO_Init(fd);

/*(1) 创建套接字*/

if((listenfd = socket(AF_INET , SOCK_STREAM , 0)) == -1)

{

perror("socket error.\n");

exit(1);

}//if

/*(2) 初始化地址结构*/

bzero(&servaddr , sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(port);

/*(3) 绑定套接字和端口*/

if(bind(listenfd , (struct sockaddr *)&servaddr , sizeof(servaddr)) < 0)

{

perror("bind error.\n");

exit(1);

}//if

/*(4) 监听*/

if(listen(listenfd , LISTENQ) < 0)

{

perror("listen error.\n");

exit(1);

}//if

/*(5) 接受客户请求,并创建线程处理*/

clilen = sizeof(cliaddr);

if((connfd = accept(listenfd , (struct sockaddr *)&cliaddr , &clilen)) < 0)

{

perror("accept error.\n");

exit(1);

}//if

printf("server: got connection from %s\n", inet_ntoa(cliaddr.sin_addr));

????????/*创建子线程处理该客户链接接收消息*/

????????if( pthread_create(&recv_tid , NULL , recv_message, &fd) == -1)

????????{

????????????????perror("pthread create error.\n");

????????????????exit(1);

????????}

while(1)

{

?char buf[MAX_LINE];

memset(buf , 0 , MAX_LINE);

int n;

if((n = recv(connfd , buf , MAX_LINE , 0)) == -1)

{

perror("recv error.\n");

exit(1);

}

sscanf(buf,"%d",&ret);

}

}

客户端:

安卓:

ui->ctnForward->setFixedSize(200,200);

????????ui->ctnBack->setFixedSize(200,200);

????????ui->ctnLeft->setFixedSize(200,200);

????????ui->ctnRight->setFixedSize(200,200);

????????ui->textshow->setFixedSize(800,500);

????????ui->ctnStop->setFixedSize(200,200);

????????ui->ctnStop->move(400,1000);

????????ui->ctnForward->move(400,770);

????????ui->ctnBack->move(400,1230);

????????ui->ctnLeft->move(100,1000);

????????ui->ctnRight->move(700,1000);

????????ui->textshow->move(150,100);

????????ui->lineEditip->setFixedSize(600,100);

????????ui->lineEditport->setFixedSize(600,100);

????????ui->lineEditip->move(360,1500);

????????ui->lineEditport->move(360,1650);

????????ui->labelip->setFixedSize(150,100);

????????ui->labelport->setFixedSize(150,100);

????????ui->labelip->move(150,1500);

????????ui->labelport->move(150,1650);

????????ui->ctnConnect->setFixedSize(200,100);

????????ui->ctnDisconnect->setFixedSize(200,100);

????????ui->ctnConnect->move(200,1900);

????????ui->ctnDisconnect->move(600,1900);

????//连接小车

void?TCPcar2::on_ctnConnect_clicked()

{

????//获取IP和端口号

????QString?ip=ui->lineEditip->text();

????qint16?port?=?ui->lineEditport->text().toInt();//字符串转换成整形

????//主动与服务器建立连接

????tcpSocket->connectToHost(QHostAddress(ip),port);

}

????//断开连接

void?TCPcar2::on_ctnDisconnect_clicked()

{

????//断开连接

????????tcpSocket->disconnectFromHost();

????????tcpSocket->close();

}

????//前进

void?TCPcar2::on_ctnForward_pressed()

{

????QString?str1="1";

???????tcpSocket->write(str1.toUtf8().data());//给小车发送数据????Utf8将qstring转qbytearray??.data()转char

?????????ui->textshow->setText("向前冲冲冲");

?????????//qDebug()<<"1";

}

void?TCPcar2::on_ctnForward_released()

{

//????QString?str0="0";

//????????tcpSocket->write(str0.toUtf8().data());

//?????????qDebug()<<"0";

}

????//后退

void?TCPcar2::on_ctnBack_pressed()

{

????QString?str2="2";

???????tcpSocket->write(str2.toUtf8().data());

?????????ui->textshow->setText("倒车请注意哟");

?????????//qDebug()<<"2";

}

void?TCPcar2::on_ctnBack_released()

{

//????QString?str0="0";

//????tcpSocket->write(str0.toUtf8().data());

//?????qDebug()<<"0";

}

????//左转

void?TCPcar2::on_ctnLeft_pressed()

{

????QString?str3="3";

????????tcpSocket->write(str3.toUtf8().data());//给小车发送数据

???????????ui->textshow->setText("左转啦");

???????????//qDebug()<<"3";

}

void?TCPcar2::on_ctnLeft_released()

{

//????QString?str0="0";

//????tcpSocket->write(str0.toUtf8().data());

//?????qDebug()<<"0";

}

????//??右转

void?TCPcar2::on_ctnRight_pressed()

{

????QString?str4="4";

???????tcpSocket->write(str4.toUtf8().data());

?????????ui->textshow->setText("右转啦");

?????????//qDebug()<<"4";

}

void?TCPcar2::on_ctnRight_released()

{

//????QString?str0="0";

//????tcpSocket->write(str0.toUtf8().data());

//?????qDebug()<<"0";

}

//添加绘图事件,QPixmap(":/image/2.png"));里面加的

//是添加资源的路径,

????//添加背景图

//void?TCPcar2::paintEvent(QPaintEvent?*event)

//{

//????QPainter?painter(this);

//????painter.drawPixmap(0,0,width(),height(),QPixmap("C:/Users/12085/Pictures/Saved?Pictures/rs7.jpg"));

//}

void?TCPcar2::on_ctnStop_clicked()

{

????QString?str0="0";

????????tcpSocket->write(str0.toUtf8().data());

?????????//qDebug()<<"0";

????????ui->textshow->setText("刹车啦!!!!!!");

}

驱动:


#include <linux/fs.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ioctl.h>

#include <linux/fs.h>
#include <linux/gpio.h>
#include <cfg_type.h>

#include <linux/miscdevice.h>

MODULE_LICENSE("GPL");

#define GPIO_MODE_INPUT ?1?
#define GPIO_MODE_OUTPUT ?0

typedef struct gpio_cfg_t
{
?? ?unsigned int gpio_no; //gpio的编号
?? ?unsigned int gpio_mode; // input/output

?? ?unsigned int init_value; // 当gpio配置成output模式时
?? ??? ??? ??? ??? ??? ??? ? //输出的初始值。
}gpio_cfg_t;


typedef struct gpio_value
{?? ?
?? ?unsigned int gpio_no; //gpio的编号
?? ?unsigned int gpio_value; //?
} gpio_value_t;


#define GPIO_CONFIG ?_IOW('G', 1, gpio_cfg_t)
#define GPIO_SET_VALUE _IOW('G', 2, gpio_value_t)
#define GPIO_GET_VALUE _IOWR('G', 3, gpio_value_t)


long gec6818_gpio_ioctl (struct file *_file, unsigned int cmd, unsigned long arg)
{
?? ?gpio_cfg_t gpio_cfg;
?? ?gpio_value_t gpio_value;
?? ?char gpio_name[12];
?? ?int ret;

?? ?
?? ?switch(cmd)
?? ?{
?? ??? ?case GPIO_CONFIG:
?? ??? ?{
?? ??? ??? ?void __user *ptr = (void __user *)arg;
?? ??? ??? ?ret = copy_from_user( (void*)&gpio_cfg, ptr, sizeof(gpio_cfg) );

?? ??? ??? ?sprintf(gpio_name, "GPIO%c%d", 'A' + gpio_cfg.gpio_no/32,?
?? ??? ??? ??? ??? ??? ??? ??? ?gpio_cfg.gpio_no%32);

?? ??? ??? ?printk(KERN_INFO "gpio num: %s mode:%s\n", gpio_name,
?? ??? ??? ??? ??? ??? ?gpio_cfg.gpio_mode == GPIO_MODE_INPUT ? "INPUT" : "OUTPUT");

?? ??? ??? ?if (gpio_cfg.gpio_mode == GPIO_MODE_INPUT)
?? ??? ??? ?{
?? ??? ??? ??? ?gpio_direction_input(gpio_cfg.gpio_no);
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?gpio_direction_output(gpio_cfg.gpio_no, gpio_cfg.init_value);
?? ??? ??? ?}
?? ??? ??? ?break;
?? ??? ?}
?? ??? ?case GPIO_SET_VALUE:
?? ??? ?{
?? ??? ??? ?void __user *ptr = (void __user *)arg;
?? ??? ??? ?ret = copy_from_user( (void*)&gpio_value, ptr, sizeof(gpio_value) );

?? ?
?? ??? ??? ?sprintf(gpio_name, "GPIO%c%d", 'A' + gpio_value.gpio_no/32,?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?gpio_value.gpio_no%32);
?? ??? ??? ?
?? ??? ??? ?printk(KERN_INFO "SET %s -> %d\n",?
?? ??? ??? ??? ?gpio_name, gpio_value.gpio_value);

?? ??? ??? ?__gpio_set_value( gpio_value.gpio_no, gpio_value.gpio_value);
?? ??? ??? ?break;
?? ??? ?
?? ??? ?}

?? ??? ?case GPIO_GET_VALUE:
?? ??? ?{
?? ??? ??? ?void __user *ptr = (void __user *)arg;
?? ??? ??? ?ret = copy_from_user( (void*)&gpio_value, ptr, sizeof(gpio_value) );
?? ??? ??? ?
?? ??? ??? ?gpio_value.gpio_value = __gpio_get_value(gpio_value.gpio_no);


?? ??? ??? ?sprintf(gpio_name, "GPIO%c%d", 'A' + gpio_value.gpio_no/32,?
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?gpio_value.gpio_no%32);
?? ??? ??? ?
?? ??? ??? ?printk(KERN_INFO "GET %s's state is %d\n",?
?? ??? ??? ??? ?gpio_name, gpio_value.gpio_value);

?? ??? ??? ?ret = copy_to_user(ptr, (void*)&gpio_value, sizeof(gpio_value));
?? ??? ??? ?break;
?? ??? ?}
?? ?

?? ??? ?default:
?? ??? ??? ?break;
?? ?}


?? ?return 0;
}


static struct file_operations gec6818_gpio_ops =
{
?? ?.unlocked_ioctl = gec6818_gpio_ioctl
};

static struct miscdevice gec_misc =?
{
?? ?.minor = MISC_DYNAMIC_MINOR,
?? ?.name = "gec6818_gpios", ?// /dev/gec6818_gpios
?? ?.fops = &gec6818_gpio_ops //文件操作

};


static int __init gec6818_gpio_drv_init(void)
{
?? ?return misc_register(&gec_misc);
}
static void __exit gec6818_gpio_drv_exit(void)
{
?? ?misc_deregister(&gec_misc);
}

module_init(gec6818_gpio_drv_init);
module_exit(gec6818_gpio_drv_exit);

#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>

MODULE_INFO(vermagic, VERMAGIC_STRING);

struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
?.name = KBUILD_MODNAME,
?.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
?.exit = cleanup_module,
#endif
?.arch = MODULE_ARCH_INIT,
};

static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 13:28:51  更:2022-01-16 13:29:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/8 5:55:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码