C++ 实现简单Tcp服务器端 -- Select方式

2023-05-16

test_server.h

#ifndef INCLUDE_TEST_SERVER_H
#define INCLUDE_TEST_SERVER_H

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <vector>

#include <winsock2.h>
#include <Ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib") 

#include <fstream>
#include <iostream>
#include <time.h>

using namespace std;

#define SIZE 60
#define FILENAME "setting.txt"
#define OUTPUTFILENAME "output.txt"

class testServer
{
public:
	testServer(void);
	~testServer(void);

	bool loadSocketLib(void);
	bool readSocketParam(std::string fileName);
	bool listenClient(void);
	bool selectSocket(void);
	bool disconnectListen(void);
	bool receiveData(void);
	bool outputDataProcessing(void);
	bool writeFile(std::string outPutFileName);


protected:
	SOCKET  s_socket_fd;
	SOCKET new_socket_fd;
	std::string ipAddr;
	uint16_t portNum;
	char r_buf[SIZE];
	std::string oustr;
	fd_set readSet, tmpSet; 

};

#endif /*INCLUDE_TEST_SERVER_H*/

test_server.cpp

#include "test_server.h"

using namespace std;

/*
 *  @brief Contructor
 */
testServer::testServer(void)
{
	s_socket_fd = INVALID_SOCKET;
	new_socket_fd = INVALID_SOCKET;
	ipAddr = "";
	portNum = 0;
	memset(r_buf, 0, (size_t)SIZE);
	oustr = "";
	FD_ZERO(&tmpSet);
	FD_ZERO(&readSet);
}

/*
 *  @brief Destructor
 */
testServer::~testServer(void) {}

/*
 *  @brief Start SOCKET library
 *  @return[in] result (ture:success  false:failure)
 */
bool testServer::loadSocketLib(void)
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 
	{
		cout << "startSOCKETlib error : error = start Socket lib failure" << endl;
		return false;
	}
	return true;
}

/*
 *  @brief read setting file(load socket param)
 *  @param [in] FileName
 *  @return[in] result (ture:success  false:failure)
 */
bool testServer::readSocketParam(std::string FileName)
{
	ifstream input(FileName.c_str());
	std::string line;
	std::vector<string> IPinfo;

	if (!input)
	{
		ipAddr = "";
		portNum = 0;
		cout << "load file error : error = no such file" << endl;
		return false;
	}
	else
	{
		input.seekg(std::ios::beg);
		while (getline(input, line))
		{
			IPinfo.push_back(line);
		}
		
		if (IPinfo[0].empty()|| IPinfo[1].empty())
		{
			cout << "read parameter error : error =  Parameter setting error" << endl;
			return false;
		}
		
		ipAddr = IPinfo[0];
		portNum = static_cast<uint16_t>(std::stol(IPinfo[1]));
		if (portNum > 1023 && portNum < 65536)
		{
			cout << "[load IPaddrs]:" << ipAddr << endl;
			cout << "[load portNum]:" << portNum << endl;
			return true;
		}
		else
		{
			cout << "read parameter error : error = invalid port number" << endl;
			return false;
		}

	}
}

/*
 *  @brief Listen for client requests
 *  @return [in] result (ture:success  false:failure)
 */
bool testServer::listenClient(void)
{
	if ((s_socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
	{
		cout << "create socket error,error = create socket  failed" << endl;
		return false;
	}

	sockaddr_in  sAddr;
	memset(&sAddr, 0, sizeof(sAddr));
	sAddr.sin_family = AF_INET;
	sAddr.sin_addr.s_addr = inet_addr(ipAddr.c_str());
	sAddr.sin_port = htons(portNum);

	if (bind(s_socket_fd, (struct sockaddr *)&sAddr, sizeof(sAddr)) == SOCKET_ERROR)
	{
		cout << "bind socket error,errno= bind socket failed" << endl;
		return false;
	}

	if (listen(s_socket_fd, 2) == SOCKET_ERROR)
	{
		cout << "listen socket error,errno = listen socket failed"<< endl;
		return false;
	}
	else
		cout << "======= start listen =======" << endl;
	
	FD_ZERO(&readSet); 
	FD_SET(s_socket_fd, &readSet); 
	cout << "start listening..." << endl;
	return true;
}

/*
 *  @brief disconnect listen
 *  @return [in] result (ture:success  false:failure)
 */
bool testServer::disconnectListen(void)
{
	if (closesocket(new_socket_fd) != INVALID_SOCKET)
	{
		new_socket_fd = INVALID_SOCKET;
	}

	if (closesocket(s_socket_fd) != INVALID_SOCKET)
	{
		s_socket_fd = INVALID_SOCKET;
		cout << "Listen disconnected" << endl;
		return true;
	}
	else
	{
		cout << "disconnect Listen error,errno = close socket failed" << endl;
		return false;
	}
}

/*
 *  @brief select Socket
 *  @return [in] result (ture:success  false:failure)
 */
bool testServer::selectSocket(void)
{
	FD_ZERO(&tmpSet);
	tmpSet = readSet;
	int fdnum;

	if ((fdnum = select(0, &tmpSet, NULL, NULL, NULL)) == SOCKET_ERROR)
	{
		return false;
	}
	else
		return true;
}

/*
 *  @brief
 *  @return [in] result (ture:success  false:failure)
 */
bool testServer::receiveData(void)
{
	sockaddr_in cAddr;
	socklen_t clen = sizeof(cAddr);
	memset(r_buf, 0, (size_t)SIZE);

	for (unsigned int i = 0; i < readSet.fd_count; i++)
	{
		if (FD_ISSET(readSet.fd_array[i], &tmpSet))
		{
			if (readSet.fd_array[i] == s_socket_fd) 
			{
				if ((new_socket_fd = accept(s_socket_fd, (SOCKADDR*)&cAddr, &clen)) == INVALID_SOCKET)
				{
					cout << "accept error,errno = accept failed" << endl;
					return false;
				}
				
				cout << "client[" << new_socket_fd <<  "]was listened" << endl;
				FD_SET(new_socket_fd, &readSet);
			}
			else 
			{
				int recvNum = recv(readSet.fd_array[i], r_buf, (size_t)SIZE, 0);
				if (recvNum == SOCKET_ERROR )
				{
					cout << "recv error,errno = recv data failed" << endl;
					FD_CLR(readSet.fd_array[i], &tmpSet);
					closesocket(tmpSet.fd_array[i]);
					return false;
				}
				else if (recvNum == 0)
				{
					cout << "client[" << tmpSet.fd_array[i] << "]was closed" << endl;
					FD_CLR(readSet.fd_array[i], &tmpSet);
					closesocket(tmpSet.fd_array[i]);
					return false;
				}
				else
					cout << "---------------------------------------" << endl;
					cout << "received data : <" << r_buf << ">" << endl;
					
			}
		}
	}
	return true;
}

/*
 *  @brief processing the data to be sent
 *  @return [in] result (ture:success  false:failure)
 */
bool testServer::outputDataProcessing(void)
{
	std::string times, hostName, recvData;

	// get timestamp
	time_t timep;
	time(&timep);
	char timestamp[64];
	strftime(timestamp, sizeof(timestamp), "%Y/%m/%d %H:%M:%S", localtime(&timep));
	times = timestamp;
	if (times == "")
	{
		cout << "data processing error:[time] is empty" << endl;
		return false;
	}

	// get host name
	char name[64];
	gethostname(name, sizeof(name));
	hostName = name;
	if (hostName == "")
	{
		cout << "data processing error:[hostName] is empty" << endl;
		return false;
	}

	// get recv data
	recvData = r_buf;
	if (recvData == "")
	{
		cout << "data processing error:[recvData] is empty" << endl;
		return false;
	}

	oustr = "<" + times + ">,<" + hostName + ">,<" + recvData + ">";
	cout << "data processing successed !" << endl;
	return true;
}

/*
 *  @brief write data to file
 *  @param  [in] outPutFileName
 *  @return [in] result (ture:success  false:failure)
 */
bool testServer::writeFile(std::string outPutFileName)
{

	ofstream OutFile;
	OutFile.open(outPutFileName.c_str(), ios::app);

	if (OutFile.is_open())
	{
		OutFile << oustr << endl;
		OutFile.close();
		cout << "Data has been written to :" << outPutFileName << endl;
		return true;
	}
	else
	{
		cout << "load file error : error = no such file" << endl;
		return false;
	}
}


///***********************  main  **************************/
int main()
{
	testServer tcpServer;

	if (tcpServer.loadSocketLib())
	{
		if (tcpServer.readSocketParam(FILENAME))
		{
			if (tcpServer.listenClient())
			{
				while (1)
				{
					if (tcpServer.selectSocket())
					{
						if (tcpServer.receiveData())
						{
							if (tcpServer.outputDataProcessing())
							{
								tcpServer.writeFile(OUTPUTFILENAME);
							}
							else
								continue;
						}
						else
							continue;
					}
					else
						break;
				}
				
			}
			else
				cout << " run [func: listenClient] fail" << endl;
		}
		else
			cout << " run [func: readSocketParam] fail" << endl;
	}
	else
		cout << " run [func: loadSocketLib] fail" << endl;

	tcpServer.disconnectListen();
	WSACleanup();
	system("pause");

	return 0;
}

test_client.h

#ifndef INCLUDE_TEST_CLIENT_H
#define INCLUDE_TEST_CLIENT_H

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <vector>

#include <winsock2.h>
#include <Ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")  

#include <fstream>
#include <iostream>

using namespace std;

#define SIZE 60
#define FILENAME "setting.txt"
#define EXIT "exit"


class testClient
{
public:
	testClient(void);
	~testClient(void);

	bool loadSocketLib(void);
	bool readSocketParam(std::string FileName);
	bool connectServer(void);
	bool disconnect(void);
	bool isConnected(void);
	bool inputData(void);
	bool wantExit(void);
	bool sendData(void);


protected:
	SOCKET c_socket_fd;
	std::string ipAddr;
	uint16_t portNum;
	std::string s_data;
};

#endif /*INCLUDE_TEST_CLIENT_H*/

test_client.cpp

#include "test_client.h"

/*
 *  @brief Contructor
 */
testClient::testClient(void)
{
	c_socket_fd = INVALID_SOCKET;
	ipAddr = "";
	portNum = 0;
	s_data = "";
}

/*
 *  @brief Destructor
 */
testClient::~testClient(void) {}

/*
 *  @brief Start SOCKET library
 *  @return[in] result (ture:success  false:failure)
 */
bool testClient::loadSocketLib(void)
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		cout << "loadSocketLib error : error = start Socket lib failure" << endl;
		return false;
	}
	return true;
}

/*
 *  @brief read setting file(load socket param)
 *  @param [in] FileName
 *  @return[in] result (ture:success  false:failure)
 */
bool testClient::readSocketParam(std::string FileName)
{
	ifstream input(FileName.c_str());
	std::string line;
	std::vector<string> IPinfo;

	if (!input)
	{
		ipAddr = "";
		portNum = 0;
		cout << "load file error : error = no such file" << endl;
		return false;
	}
	else
	{
		input.seekg(std::ios::beg);		
		while (getline(input, line))
		{
			IPinfo.push_back(line);
		}

		if (IPinfo[0].empty() || IPinfo[1].empty())
		{
			cout << "read parameter error : error =  Parameter setting error" << endl;
			return false;
		}

		ipAddr = IPinfo[0];
		portNum = static_cast<uint16_t>(std::stol(IPinfo[1]));
		if (portNum > 1023 && portNum < 65536)
		{
			cout << "[load IPaddrs]:" << ipAddr << endl;
			cout << "[load portNum]:" << portNum << endl;
			return true;
		}
		else
		{
			cout << "read parameter error : error = invlid port number" << endl;
			return false;
		}

	}
}

/*
 *  @brief connect with TCP server
 *  @return [in] result (ture:success  false:failure)
 */
bool testClient::connectServer(void)
{
	if (c_socket_fd != INVALID_SOCKET)
	{
		cout << "is connected " << endl;
		return true;
	}

	if ((c_socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
	{
		cout << "socket error,errno= create socket failed"<< endl;
		return false;
	}
	cout << "create socket successed " << endl;

	sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(ipAddr.c_str());
	addr.sin_port = htons(portNum);

	if (connect(c_socket_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
	{
		cout << "connect error,errno = socket connect failed" << endl;
		return false;
	}
	return true;
}

/*
 *  @brief disconnect from TCP server
 *  @return [in] result (ture:success  false:failure)
 */
bool testClient::disconnect(void)
{
	if (c_socket_fd == INVALID_SOCKET)
	{
		cout << "disconnected" << endl;
		return true;
	}

	if (closesocket(c_socket_fd) != INVALID_SOCKET)
	{
		c_socket_fd = INVALID_SOCKET;
		cout << "disconnected" << endl;
		return true;
	}
	else
	{
		cout << "disconnect error,errno = close socket failed" << endl;
		return false;
	}
}

/*
 *  @brief confirm with TCP server connection
 *  @return [in] result (ture:success  false:failure)
 */
bool testClient::isConnected(void)
{
	if (c_socket_fd != INVALID_SOCKET)
	{
		return true;
	}
	else
		return false;
}

/*
 *  @brief processing input data
 *  @return [in] result (ture:success  false:failure)
 */
bool testClient::inputData(void)
{	
	unsigned int i;
	std::string s_data_buf = "";

	cout << "place input data..." << endl;
	if (getline(cin, s_data))
	{
		if (s_data.length() > SIZE)
		{
			cout << "inputData error,error = input limit exceeded" << endl;
			return false;
		}
		for (i = 0; i < s_data.length(); i++)
		{
			if (isascii(s_data[i]))
			{
				s_data_buf += s_data[i];
			}
		}
		s_data = s_data_buf;
		return true;
	}
	else
	{
		cout << "inputData error,error = Data input failed" << s_data << endl;
		return false;
	}
}

/*
 *  @brief Determine if it need to be closed
 *  @return [in] result (ture:success  false:failure)
 */
bool testClient::wantExit(void)
{
	if (s_data == EXIT)
	{
		return true;
	}
	else
		return false;
}

/*
 *  @brief send data to server
 *  @return [in] result (ture:success  false:failure)
 */
bool testClient::sendData(void)
{
	if (c_socket_fd != INVALID_SOCKET)
	{
		if (send(c_socket_fd, s_data.c_str(), s_data.length(), 0) == SOCKET_ERROR) {
			cout << "send data failed : send function error" << endl;
			c_socket_fd = INVALID_SOCKET;
			return false;
		}
		else
		{
			cout << "<" << s_data << "> has been sent successfully " << endl;
			cout << "------------------------------------------- " << endl;
			s_data = "";
			return true;
		}
	}
	else
	{
		cout << "send data failed :  c_socket_fd is invalid" << endl;
		return false;
	}

}

//***********************  main  **************************/
int main()
{
	testClient tcpclient;

	if (tcpclient.loadSocketLib())
	{
		if (tcpclient.readSocketParam(FILENAME))
		{
			while(1)
			{ 
				if (tcpclient.connectServer())
				{
					while (1)
					{
						if (tcpclient.isConnected())
						{
							if (tcpclient.inputData())
							{
								if (tcpclient.wantExit())
								{
									cout << "stop send data" << endl;
									break;
								}
								else
								{
									tcpclient.sendData();
								}
							}
							else
								continue;
						}
						else
							break;
					}
					if (tcpclient.wantExit())
					{
						break;
					}
				}
				else
				{
					tcpclient.disconnect();
					cout << "trying to connect again..." << endl;
				}
			}
		}
		else
			cout << " run [func: readSocketParam] fail" << endl;
	}
	else
		cout << " run [func: loadSocketLib] fail" << endl;

	tcpclient.disconnect();
	WSACleanup();
	system("pause");
	return 0;
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 实现简单Tcp服务器端 -- Select方式 的相关文章

  • STM32F1C8T6Flash读取音频和DAC播放

    文章目录 一 Flash简介1 Flash原理2 STM32F1中的Flash 二 Flash地址空间的数据读取1 题目要求2 CUbeMX工程建立3 Keil工程修改4 STlink调试说明5 调试运行 三 基于片内Flash的提示音播放
  • C语言中的头文件为什么不能定义变量

    1 前提 在实际项目中 xff0c 会遇到这样的情况 xff0c 在链接阶段 xff0c 会提示定义在头文件中的变量 xff0c 重定义 xff0c 然后将将头文件中的变量定义成static类型 xff0c 然后 xff0c 不报错误了 例
  • Ubuntu16.04安裝ROS

    此文章在前人的基礎上 xff0c 並把安裝遇到的問題寫出來 Ubuntu16 04安装ROS Kinetic详细过程 https blog csdn net weixin 43159148 article details 83375218
  • B-spline的理解与路径规划中的应用及C++代码的实现

    研究项目 xff0c 无人机的路径规划 xff0c 需要用到B样条 xff0c 所以在此写下B spline的结合C 43 43 代码的理解以及在项目中的应用 一 阶数p 阶数 61 所有权重中t的最高次幂 61 控制点数量 1 xff1b
  • Jetson TX2 各个模式

    Jetson TX2 工作模式及相应的CPU和GPU频率 xff1a 上电的时候 xff0c 默认最低功耗模式1 xff0c 风扇不转 1 直接运行home下的jetson clocks sh xff0c 开启最大频率 sudo jetso
  • 网络通信基础知识—网络通信的发展历程

    网络通信基础知识 网络通信的发展历程 xff08 1 xff09 单机阶段 xff08 2 xff09 局域网阶段 xff08 3 xff09 广域网internet阶段 xff08 很多个局域网之间通信 xff09 xff08 4 xff
  • win7下装ubuntu双系统 硬盘安装详细教程

    本文转载自http www linuxidc com Linux 2014 10 108430 htm https jingyan baidu com article e4d08ffdace06e0fd2f60d39 html 在自己安装过
  • ROS导航——配置机器人的导航功能(move_base包)

    中间部分是整个导航的核心部分 xff0c 由move base功能包提供 配置如下 xff1a lt launch gt lt node pkg 61 34 move base 34 type 61 34 move base 34 resp
  • 基于docker安装tensorflow

    最近在自学机器学习 xff0c 大热的Tensorflow自然不能错过 xff0c 所以首先解决安装问题 xff0c 为了不影响本地环境 xff0c 所以本文基于Docker来安装Tensorflow xff0c 我的环境是Ubuntu16
  • okHttpUtil工具类

    pom文件 lt dependency gt lt groupId gt com squareup okhttp3 lt groupId gt lt artifactId gt okhttp lt artifactId gt lt vers
  • 基于采样的RRT/RRT*/RRT_connect算法笔记及C++实现

    本文记录常见的基于采样的RRT算法及相关改进算法 xff08 RRT xff0c RRT connect xff09 的原理和代码实现效果 与上一章介绍A 算法的文章不同 xff0c 本文会先给出几种算法之间的效果对比 xff0c 先有个直
  • STM32F103ZE驱动PMW3901光流模块

    本文将会简单的介绍如何使用STM32F103ZE驱动PMW3901光流模块 xff0c 使用标准库 所用材料如下 一块 STM32F103最小系统板以及一个 PMW3901光流模块 通过查阅PMW3901的数据手册可以得知 xff0c 该芯
  • 计算两圆相交面积

    转自 xff1a 模板 求两圆相交面积 xff08 模板 xff09 两圆相交分如下集中情况 xff1a 相离 相切 相交 包含 设两圆圆心分别是O1和O2 xff0c 半径分别是r1和r2 xff0c 设d为两圆心距离 又因为两圆有大有小
  • 深蓝学院-移动机器人运动规划重点笔记

    移动机器人运动规划笔记 xff0c 转载自https blog csdn net wqwqqwqw1231 article details 107310965 感谢原作者的总结 xff01
  • TFmini Plus在Arduino上的开发例程(二)

    本例程以Arduino Uno板为例 xff0c 通过Arduino实现TFmini Plus相关指令的写入 xff0c 上行数据的读取 判断和测量数据的获取打印 xff0c 主要帮助客户快速熟悉我公司雷达 xff0c 减少产品的研发周期
  • Linux命令发送Http GET/POST请求

    Linux命令发送Http GET POST请求 Get请求 1 使用curl命令 xff1a curl span class token string 34 http www baidu com 34 span 如果这里的URL指向的是一
  • VSCode 常用设置项

    代码编辑工具VSCode 常用设置项 span class token punctuation span span class token comment VScode主题配置 span span class token string 34
  • 机器人运动控制-上位机通讯

    机器人 xff0c 无论是工业机器人还是服务机器人等多种类机器人 xff0c 都有自己的控制器 在他们的控制面板上 xff0c 我们可以通过简单的操作和程序指令 xff0c 让机器人自行运动 为了让机器人更加智能 xff0c 我们需要在机器
  • Imu误差模型、零偏、零偏稳定性

    原文链接 零偏 xff0c 零偏稳定性和零偏重复性 xff0c IMU误差模型 什么是零偏 xff08 Bias xff09 在陀螺静止时 xff0c 陀螺仪仍会 xff0c 以规定时间内测得的输出量平均值相应的等效输入角速率表示 xff0
  • 海思3516a实现OSD叠加水印

    文章目录 前言一 三个文件的编译二 海思SDK使用步骤1 创建叠加字符2 添加叠加区域到视频通道 总结 前言 两天的努力终于实现了 xff0c 激动 xff01 在网上查阅了各种资料 xff0c 只是有零散的信息 xff0c 海思3516a

随机推荐

  • 结合下图,说明UART的工作原理

    结合下图 xff0c 说明UART的工作原理 UART提供三个独立的异步串行I O口 xff0c 他们可以运行于中断模式或者DMA模式 xff0c 也就是说UART可以产生中断请求或者DMA请求 xff0c 以便在CPU和UART之间传输数
  • 深入理解计算机系统 -- 大端与小端字节序

    一 大端字节序 vs 小端字节序 字节序指一个多字节对象在内存中存储的方式 xff0c 小端字节序机器在存储多字节对象时采用低地址存低有效字节的策略 xff0c 大端则恰恰相反 字节序由CPU架构决定 xff0c 与操作系统无直接关系 像常
  • TCP连接建立

    TCP 一种面向来连接的 可靠的 基于字节流的传输层通信协议 面向连接 xff1a 数据在发送之前必须在两端建立连接 xff0c 方法就是我们熟知的三次握手连接 可靠传输 xff1a 通过多种机制来保证数据的正确传输 xff0c 比如序列号
  • UDP接收端收不到广播的消息问题排查

    网络调试助手可以互相发送 xff0c 而你的UDP广播代码却不行 你是广播 是不会被路由器转发的 但是在同一个交换机下 是可以收到广播的 还有就是 电脑的虚拟网卡会拦截广播操作 xff0c 因为你没有指定一个地址 xff0c 所以代码正确的
  • STM32带FIFO的DMA传输应用示例

    STM32系列芯片都内置DMA外设 xff0c 其中很多系列的DMA配备了FIFO 这里以STM32F429芯片及开发板为例 xff0c 演示一下带FIFO的DMA传输实现过程 大致情况是这样的 xff0c 我用TIMER1通道1的比较事件
  • 两种方式判断内存的大小端存储方式

    1 目的 xff1a 判断ubuntu操作系统的内存属于大端还是小端存储 2 源代码 两种方法判断大小端 xff08 处理器取值时的字节序 xff09 xff1a 1 字符指针 2 联合体 法1 if 1 include lt stdio
  • 字符串:求str1在str2中首次出现的位置。

    span class token macro property span class token directive keyword include span span class token string lt stdio h gt sp
  • 基于ROS利用客户端和服务端实现C++节点和python节点间传送图像

    基于ROS利用客户端和服务端实现C 43 43 节点和python节点间传送图像 配置ROS下和python3通信以及配置python3可用的cv bridge 环境安装和使用 参考 xff1a https blog csdn net qq
  • iMaxB6充电介绍

    iMaxB6是一款多用途充电器 xff0c 能够为Li ion Li Poly Li Fe Ni Cd Ni MH和Pb类型电池充电 xff0c 支持6串以内的平衡充电 简要步骤 xff1a 1 连接正负电源 xff1b 2 连接平衡线 x
  • 基于stm32串口环形缓冲队列处理机制

    原文链接 xff1a 基于stm32串口环形缓冲队列处理机制 入门级 xff08 单字节 xff09 串口环形缓冲区实验 1 1 实验简介 最简单的串口数据处理机制是数据接收并原样回发的机制是 xff1a 成功接收到一个数 xff0c 触发
  • 源码安装nginx 1.23.1

    先看看仓库们 yum list nginx 已加载插件 xff1a fastestmirror langpacks Loading mirror speeds from cached hostfile base mirrors aliyun
  • Sublime Text运行C和C++程序

    原文链接 xff1a Sublime Text运行C和C 43 43 程序 Sublime Text 是一款当下非常流行的文本编辑器 xff0c 其功能强大 xff08 提供有众多的插件 xff09 界面简洁 还支持跨平台使用 xff08
  • keilC51编译常见错误和警告说明

    如对编译出错感兴趣的网友能否把你们常遇到的错误信息收集起来并提出最终的解决办法加以归纳以期共享 xff01 1 L15 重复调用 WARNING L15 MULTIPLE CALL TO SEGMENT SEGMENT PR SPI REC
  • RS485的电路以及相关波形

    1 RS485的电路 xff0c 要注意RE引脚一般是和DE引脚接在一起的 2 差分信号AB的波形 xff0c 高电平6 2v左右 xff0c 低电平 3v 3 A点的波形 4 B点波形 5 接收RX的波形
  • Ubuntu安装cmake

    Ubuntu18 04安装cmake 转载自https www cnblogs com yanqingyang p 12731855 html 一 使用安装命令 span class token function sudo span apt
  • C/C++混淆点-strcat和strcpy区别

    一 原因分析 假设 xff1a char str 61 NULL str 61 new char 11 你想为字符串str开辟一个存储十个字符的内存空间 xff0c 然后你现在有两个字符串 xff1a char c1 61 34 abc 3
  • QGC 添加电机测试功能

    组装过程中为了测试电机的连接以及转向 xff0c 现将电机测试功能单独制作一个页面 xff0c 以便使用 一 xff0c 效果 原型 实际效果总是差那么一丢丢 二 xff0c 实现思路 MavlinkConsole 功能 xff0c 可以在
  • 川崎duAro机器人 ROS_moveit demo

    说明 demo cpp Author hiics include lt ros ros h gt include lt iostream gt MoveIt include lt moveit move group interface mo
  • Windows10 下C/C++网络编程基本:socket实现tcp的例子

    1 说明 待编辑 2 代码 test server h span class token macro property span class token directive keyword ifndef span INCLUDE TEST
  • C++ 实现简单Tcp服务器端 -- Select方式

    test server h span class token macro property span class token directive keyword ifndef span INCLUDE TEST SERVER H span