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 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> win32 基础数据发送与接收 -> 正文阅读

[网络协议]win32 基础数据发送与接收

前言

Win32中发送基础网络数据相比起其他语言如java可能比较复杂。

大致流程:

  1. 导入Ws2_32.lib
  2. 根据一定规范初始化Ws2_32.lib
  3. 创建套接字对象,用于指定协议类型
  4. 绑定套接字所指定的端口
  5. 调用收发函数
  6. 资源回收
  • (1)导入Ws2_32.lib

有两种方式指示导入动态库

  1. 编译宏指示连接器
#pragma comment(lib,"Ws2_32.lib")
  1. VS中配置

在这里插入图片描述

  • (2)初始化Ws2_32.lib

WSAStartup 文档

这里我们直接抄官方文档代码即可


int main()
{

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		/* Tell the user that we could not find a usable */
		/* Winsock DLL.                                  */
		printf("WSAStartup failed with error: %d\n", err);
		return 1;
	}

	/* Confirm that the WinSock DLL supports 2.2.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.2 in addition to 2.2, it will still return */
	/* 2.2 in wVersion since that is the version we      */
	/* requested.                                        */

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
		/* Tell the user that we could not find a usable */
		/* WinSock DLL.                                  */
		printf("Could not find a usable version of Winsock.dll\n");
		WSACleanup();
		return 1;
	}
	else
		printf("The Winsock 2.2 dll was found okay\n");
	
	WSACleanup();
}

  • (3) 创建套接字对象,用于指定协议类型

	//(2)创建套接字对象,用于指定协议类型
	//https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
	SOCKET sockServer = socket(
		AF_INET,//指定协议是IPV4 还是IPV6.AF_INET是IPV4,AF_INET6是IPV6
		SOCK_DGRAM,//指定是TCP(SOCK_STREAM)或者UDP(SOCK_DGRAM)
		IPPROTO_UDP//指定具体的协议类型,如ICMP,IPPROTO_TCP或IPPROTO_UDP 
	);

	if (sockServer == INVALID_SOCKET)
	{
		printf("创建socket失败 \r\n");
		return 0;
	}
  • (4) 绑定套接字所指定的端口
//(3)绑定套接字所指定的端口
	sockaddr_in si;
	si.sin_family = AF_INET;
	//htons函数用于转化大小端,网络传输字节流统一采用大端
	//但在x86使用小端编码,所以利用htons屏蔽大小端
	si.sin_port = htons(0x5566);
	//inet_addr同上
	si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	//绑定端口
	int nRet = bind(
		sockServer,//指定的协议
		(sockaddr *)&si,//指定的端口信息
		sizeof(si)
	);
	if (nRet == SOCKET_ERROR)
	{
		printf("绑定端口失败\r\n");
		WSACleanup();
		return 0;
	}

(5). 调用收发函数 和 (6) 资源回收

/接收数据
	sockaddr_in siRecf;

	char aryBuf[MAXBYTE] = { 0 };
	int nNameLen = sizeof(siRecf);
	while (true)
	{
		//接收信息
		nRet = recvfrom(
		sockServer, //协议
		aryBuf,//接收的字节数组
		 sizeof(aryBuf),//接收大小
		  0,//一些标志功能 传入0即可
		   (sockaddr *)&siRecf,//用于接收发送方的信息,比如从哪个网络发过来的
		    &nNameLen
		    );
	
		if (nRet == SOCKET_ERROR)
		{
			printf("接收信息错误\r\n");
			WSACleanup();
			return 0;
		}

		std::cout << "收到客户端信息:" << aryBuf << std::endl;

		char aryBuf[MAXBYTE] = { "hello Server" };

		printf("请输入要发送的数据\r\n");

		std::cin >> aryBuf;
		nRet = sendto(sockServer, aryBuf, sizeof(aryBuf), 0, (sockaddr *)&siRecf, sizeof(siRecf));
		if (nRet == SOCKET_ERROR)
		{
			printf("发送数据错误 \r\n");
			WSACleanup();
			return 0;
		}

	}




	//关闭资源


	closesocket(sockServer);

	/* The Winsock DLL is acceptable. Proceed to use it. */

	/* Add network programming using Winsock here */

	/* then call WSACleanup when done using the Winsock dll */

	WSACleanup();



	return 0;

我们看下完整服务器的完整代码:

#include <iostream>

#include <Winsock2.h>
//导入动态库
#pragma comment(lib,"Ws2_32.lib")

int main()
{

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		/* Tell the user that we could not find a usable */
		/* Winsock DLL.                                  */
		printf("WSAStartup failed with error: %d\n", err);
		return 1;
	}

	/* Confirm that the WinSock DLL supports 2.2.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.2 in addition to 2.2, it will still return */
	/* 2.2 in wVersion since that is the version we      */
	/* requested.                                        */

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
		/* Tell the user that we could not find a usable */
		/* WinSock DLL.                                  */
		printf("Could not find a usable version of Winsock.dll\n");
		WSACleanup();
		return 1;
	}
	else
		printf("The Winsock 2.2 dll was found okay\n");


	//(2)创建套接字对象,用于指定协议类型
	//https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
	SOCKET sockServer = socket(
		AF_INET,//指定协议是IPV4 还是IPV6.AF_INET是IPV4,AF_INET6是IPV6
		SOCK_DGRAM,//指定是TCP(SOCK_STREAM)或者UDP(SOCK_DGRAM)
		IPPROTO_UDP//指定具体的协议类型,如ICMP,IPPROTO_TCP或IPPROTO_UDP 
	);

	if (sockServer == INVALID_SOCKET)
	{
		printf("创建socket失败 \r\n");
		return 0;
	}

	//(3)绑定套接字所指定的端口
	sockaddr_in si;
	si.sin_family = AF_INET;
	//htons函数用于转化大小端,网络传输字节流统一采用大端
	//但在x86使用小端编码,所以利用htons屏蔽大小端
	si.sin_port = htons(0x5566);
	//inet_addr同上
	si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	//绑定端口
	int nRet = bind(
		sockServer,//指定的协议
		(sockaddr *)&si,//指定的端口信息
		sizeof(si)
	);

	if (nRet == SOCKET_ERROR)
	{
		printf("绑定端口失败\r\n");
		WSACleanup();
		return 0;
	}


	//接收数据
	sockaddr_in siRecf;

	char aryBuf[MAXBYTE] = { 0 };
	int nNameLen = sizeof(siRecf);
	while (true)
	{
		nRet = recvfrom(sockServer, aryBuf, sizeof(aryBuf), 0, (sockaddr *)&siRecf, &nNameLen);
		if (nRet == SOCKET_ERROR)
		{
			printf("接收信息错误\r\n");
			WSACleanup();
			return 0;
		}

		std::cout << "收到客户端信息:" << aryBuf << std::endl;

		char aryBuf[MAXBYTE] = { "hello Server" };

		printf("请输入要发送的数据\r\n");

		std::cin >> aryBuf;
		nRet = sendto(sockServer, aryBuf, sizeof(aryBuf), 0, (sockaddr *)&siRecf, sizeof(siRecf));
		if (nRet == SOCKET_ERROR)
		{
			printf("发送数据错误 \r\n");
			WSACleanup();
			return 0;
		}

	}




	//关闭资源


	closesocket(sockServer);

	/* The Winsock DLL is acceptable. Proceed to use it. */

	/* Add network programming using Winsock here */

	/* then call WSACleanup when done using the Winsock dll */

	WSACleanup();



	return 0;

}

客户端代码也是差不多:


#include <iostream>

#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

using namespace std;

int main()
{

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		/* Tell the user that we could not find a usable */
		/* Winsock DLL.                                  */
		printf("WSAStartup failed with error: %d\n", err);
		return 1;
	}

	/* Confirm that the WinSock DLL supports 2.2.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.2 in addition to 2.2, it will still return */
	/* 2.2 in wVersion since that is the version we      */
	/* requested.                                        */

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
		/* Tell the user that we could not find a usable */
		/* WinSock DLL.                                  */
		printf("Could not find a usable version of Winsock.dll\n");
		WSACleanup();
		return 1;
	}
	else
		printf("The Winsock 2.2 dll was found okay\n");



	//https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
	SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	if (sockClient == INVALID_SOCKET)
	{
		printf("创建socket失败 \r\n");
		return 0;
	}

	sockaddr_in si;
	si.sin_family = AF_INET;
	si.sin_port = htons(0x77988);
	si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	int nRet = bind(
		sockClient,
		(sockaddr *)&si,
		sizeof(si)
	);

	if (nRet == SOCKET_ERROR)
	{
		printf("绑定端口失败\r\n");
		WSACleanup();
		return 0;
	}
	//发送数据
	sockaddr_in siSever;

	siSever.sin_family = AF_INET;

	siSever.sin_port = htons(0x5566);//传入0 指定随机端口

	siSever.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");


	while (true)
	{

		char aryBuf[MAXBYTE] = { "hello Server" };
		
		printf("请输入要发送的数据\r\n");

		cin >> aryBuf;
		nRet = sendto(sockClient, aryBuf, sizeof(aryBuf), 0, (sockaddr *)&siSever, sizeof(siSever));
		if (nRet == SOCKET_ERROR)
		{
			printf("发送数据错误 \r\n");
			WSACleanup();
			return 0;
		}

		//接收数据
		sockaddr_in siRecf;

		char aryBuf2[MAXBYTE] = { 0 };
		int nNameLen = sizeof(siRecf);
		nRet = recvfrom(sockClient, aryBuf2, sizeof(aryBuf2), 0, (sockaddr *)&siRecf, &nNameLen);
		if (nRet == SOCKET_ERROR)
		{
			printf("接收信息错误\r\n");
			WSACleanup();
			return 0;
		}
		cout <<"收到服务端信息:" <<aryBuf2 << endl;
	}




	//关闭资源


	closesocket(sockClient);

	/* The Winsock DLL is acceptable. Proceed to use it. */

	/* Add network programming using Winsock here */

	/* then call WSACleanup when done using the Winsock dll */

	WSACleanup();

	return 0;
}

效果图:
在这里插入图片描述

上面输入 I come from China 服务端分开接收到, 是因为客户端cin没有一次性接收到一行,可以改用cin.getline

接下来看TCP例子就简单多了

TCP服务端:

// TCPServer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<WinSock2.h>
#include<WS2tcpip.h>
#pragma comment(lib,"Ws2_32.lib")
//开启一个线程不断的处理收发消息
DWORD WINAPI HandleClientThreadFunc(LPVOID lpParam) {

	SOCKET sockClient = *((SOCKET*)lpParam);
	while (true)
	{
		//收发数据
		char buf[MAXBYTE] = { 0 };
		
		int iResult = recv(sockClient, buf, MAXBYTE, 0);

		if (iResult > 0)
			printf("Bytes received: %d   content %s \n", iResult, buf);
		else if (iResult == 0) {
			printf("Connection closed\n");
			return 0;
		}
		else {
			printf("recv failed: %d\n", WSAGetLastError());
			return 0;
		}


		char aryBuffSend[] = { "server recv ok \r\n" };

		int nRet = send(sockClient, aryBuffSend, sizeof(aryBuffSend), 0);

		if (nRet == SOCKET_ERROR)
		{
			printf("发送错误\r\n");
		}
	}
	closesocket(sockClient);
}
int main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		/* Tell the user that we could not find a usable */
		/* Winsock DLL.                                  */
		printf("WSAStartup failed with error: %d\n", err);
		return 1;
	}

	/* Confirm that the WinSock DLL supports 2.2.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.2 in addition to 2.2, it will still return */
	/* 2.2 in wVersion since that is the version we      */
	/* requested.                                        */

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
		/* Tell the user that we could not find a usable */
		/* WinSock DLL.                                  */
		printf("Could not find a usable version of Winsock.dll\n");
		WSACleanup();
		return 1;
	}
	else
		printf("The Winsock 2.2 dll was found okay\n");


	//创建socket
	SOCKET sockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sockServer == INVALID_SOCKET)
	{
		printf("socket创建失败 ,请重启\r\n");
		return 0;
	}
	//绑定端口
	sockaddr_in siServer;
	siServer.sin_family = AF_INET;
	siServer.sin_port = htons(0x5566);
	int nRet = InetPton(AF_INET, "127.0.0.1", &siServer.sin_addr.s_addr);
	//等于1表示成功
	if (nRet != 1)
	{
		printf("错误");
		return 0;
	}

	nRet = bind(sockServer, (sockaddr*)&siServer, sizeof(siServer));


	if (nRet == SOCKET_ERROR)
	{
		printf("绑定端口失败,请重启 \r\n");
		return 0;
	}
	//监听
	nRet = listen(sockServer, SOMAXCONN);
	if (nRet != 0)
	{
		printf("绑定端口失败,请重启 \r\n");
		return 0;
	}
	//等候连接
	int len;
	sockaddr_in si;

	int nLen = sizeof(si);

	while (true)
	{
		SOCKET  resultSocket = accept(sockServer, (sockaddr*)&si, &nLen);
		if (resultSocket == INVALID_SOCKET)
		{
			printf("accept失败,请重启 \r\n");
			continue;
		}
		HANDLE handle = CreateThread(NULL, 0, HandleClientThreadFunc, &resultSocket, 0, NULL);
	
		CloseHandle(handle);
	}


	//关闭自身
	closesocket(sockServer);

	/* The Winsock DLL is acceptable. Proceed to use it. */

	/* Add network programming using Winsock here */

	/* then call WSACleanup when done using the Winsock dll */

	WSACleanup();
}

tcp客户端

// TCPClient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

#include <iostream>
#include<WinSock2.h>
#include<WS2tcpip.h>
#pragma comment(lib,"Ws2_32.lib")
#include<stdio.h>
int main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		/* Tell the user that we could not find a usable */
		/* Winsock DLL.                                  */
		printf("WSAStartup failed with error: %d\n", err);
		return 1;
	}

	/* Confirm that the WinSock DLL supports 2.2.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.2 in addition to 2.2, it will still return */
	/* 2.2 in wVersion since that is the version we      */
	/* requested.                                        */

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
		/* Tell the user that we could not find a usable */
		/* WinSock DLL.                                  */
		printf("Could not find a usable version of Winsock.dll\n");
		WSACleanup();
		return 1;
	}
	else
		printf("The Winsock 2.2 dll was found okay\n");


	//创建socket
	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sockClient == INVALID_SOCKET)
	{
		printf("socket创建失败 ,请重启\r\n");
		return 0;
	}



	sockaddr_in siServer;
	siServer.sin_family = AF_INET;
	siServer.sin_port = htons(0x5566);
	int nRet = InetPton(AF_INET, "127.0.0.1", &siServer.sin_addr.s_addr);
	nRet = connect(sockClient, (sockaddr*)&siServer, sizeof(siServer));

	if (nRet== SOCKET_ERROR)
	{
		printf("连接服务器失败,请重试\r\n");
		return 0;
	}

	while (true)
	{
		char aryBuffSend[] = { "Hi,I'm client  \r\n" };
		
		printf("请输入发送的数据\r\n");
		std::cin >> aryBuffSend;
		
		nRet = send(sockClient, aryBuffSend, sizeof(aryBuffSend), 0);

		if (nRet == SOCKET_ERROR)
		{
			printf("发送错误\r\n");
		}

		//收发数据
		char buf[MAXBYTE] = { 0 };

		int iResult = recv(sockClient, buf, MAXBYTE, 0);

		if (iResult > 0)
			printf("Bytes received: %d\n", iResult);
		else if (iResult == 0)
			printf("Connection closed\n");
		else {
			printf("recv failed: %d\n", WSAGetLastError());
		}

		printf("收到信息:%s", buf);
	}
	




	//关闭自身
	closesocket(sockClient);

	/* The Winsock DLL is acceptable. Proceed to use it. */

	/* Add network programming using Winsock here */

	/* then call WSACleanup when done using the Winsock dll */

	WSACleanup();
}

ICMP相关代码

// TCPClient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

#include <iostream>
#include<WinSock2.h>
#include<WS2tcpip.h>
#pragma comment(lib,"Ws2_32.lib")
#include<stdio.h>


typedef struct tagICMP {
	BYTE type;
	BYTE code;
	WORD checksum;
	WORD ident;
	WORD seq;
	BYTE data[32];
}ICMP, *PICMP;
unsigned short in_cksum(unsigned short *addr, int len)
{
	int sum = 0;
	unsigned short res = 0;
	while (len > 1) {
		sum += *addr++;
		len -= 2;
		// printf("sum is %x.\n",sum);
	}
	if (len == 1) {
		*((unsigned char *)(&res)) = *((unsigned char *)addr);
		sum += res;
	}
	sum = (sum >> 16) + (sum & 0xffff);
	sum += (sum >> 16);
	res = ~sum;
	return res;
}


int main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		/* Tell the user that we could not find a usable */
		/* Winsock DLL.                                  */
		printf("WSAStartup failed with error: %d\n", err);
		return 1;
	}

	/* Confirm that the WinSock DLL supports 2.2.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.2 in addition to 2.2, it will still return */
	/* 2.2 in wVersion since that is the version we      */
	/* requested.                                        */

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
		/* Tell the user that we could not find a usable */
		/* WinSock DLL.                                  */
		printf("Could not find a usable version of Winsock.dll\n");
		WSACleanup();
		return 1;
	}
	else
		printf("The Winsock 2.2 dll was found okay\n");


	//创建socket
	SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

	if (sock == INVALID_SOCKET)
	{
		printf("socket创建失败 ,请重启\r\n");
		WSACleanup();
		return 0;
	}
	ICMP icmp;
	icmp.type = 8;
	icmp.code = 0;
	icmp.checksum = 0;
	memcpy(icmp.data, "abcdefghijklmnopqrstuvwabcdefghi", sizeof icmp.data);
	icmp.checksum = in_cksum((unsigned short *)&icmp, sizeof(icmp));

	struct hostent FAR* pHostent = gethostbyname("www.baidu.com");
	sockaddr_in siServer;
	siServer.sin_family = AF_INET;
	siServer.sin_port = 0;
	siServer.sin_addr.S_un.S_addr = *(PULONG)pHostent->h_addr_list[0];

	int nRet = sendto(sock, (char *)&icmp, sizeof(icmp), 0, (sockaddr*)&siServer, sizeof(siServer));

	if (nRet == SOCKET_ERROR)
	{
		printf("发送数据失败");
		WSACleanup();
		return 0;
	}



	sockaddr_in siRecv;
	int nNameLen = sizeof(siRecv);
	char aryBuf0[MAXBYTE] = { 0 };


	nRet = recvfrom(sock, aryBuf0, sizeof aryBuf0, 0, (sockaddr*)&siRecv, &nNameLen);
	if (nRet == SOCKET_ERROR)
	{
		printf("收到数据失败");
		WSACleanup();
		return 0;
	}

	//关闭自身
	closesocket(sock);

	/* The Winsock DLL is acceptable. Proceed to use it. */

	/* Add network programming using Winsock here */

	/* then call WSACleanup when done using the Winsock dll */

	WSACleanup();
}

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

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 17:43:14-

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