超详细c语言简化tcp通信接口(多线程实现一个服务端处理多个客户端服务)

2023-05-16

超详细c语言tcp通信接口

  • 1、可下载源码(客户端 || 服务端通信)
  • 2、说明
  • 3、接口代码
  • 4、客户端通信main_client_demo.c
  • 5、服务端通信main_server_demo.c

1、可下载源码(客户端 || 服务端通信)

tcp通信代码资源
在这里插入图片描述

2、说明

功能:tcp服务端与多个客户端进行通信(服务端通过多线程方式处理客户端服务),初始设置参数,解决服务端重启出现地址占用问题

编译:
make clean
make

执行:
(tcp服务端,系统中只能运行一个)
./server
在这里插入图片描述

(tcp客户端,可运行多个,打开另外的终端窗口执行)
./client
在这里插入图片描述

3、接口代码

.h头文件

/*************************************************
Function:tcp 服务端和客户端总接口,多线程实现一个服务端处理多个客户端通信服务
author:zyh
date:2020.4
**************************************************/

#ifndef _TCP_CLIENT_AND_SERVER_H_
#define _TCP_CLIENT_AND_SERVER_H_

int tcp_creat_socket(void);//创建socket
int tcp_client_connect(int sockfd, char *server_ip, int server_port);//tcp客户端连接服务器
int tcp_send(int sockfd,  void *sendBuf,  int len);//tcp发送消息
int tcp_blocking_rcv(int sockfd, void *recvBuf, int len);//tcp堵塞接收消息
int tcp_noblocking_rcv(int sockfd,  void *recvBuf, int len, int timeval_sec, int timeval_usec);//tcp非堵塞接收消息
void tcp_close(int sockfd);//tcp关闭socket通信

//服务端多出来的部分
int tcp_server_bind_and_listen(int sockfd, char *server_ip, int server_port, int max_listen_num);//tcp服务器绑定端口、监听设置
int tcp_server_wait_connect(int sockfd);//tcp阻塞等待客户端连接
void tcp_server_creat_pthread_process_client(int *new_sockfd, void* (*callBackFun)(void*));//服务端每接收到新的客户端连接,就创建新线程提供服务,外部需要重写处理消息的回调函数,参考void *tcp_server_callBackFun_demo(void *ptr)
void *tcp_server_callBackFun_demo(void *ptr);//callBackFun:处理客户端消息的回调函数,示例

#endif

.c源码

/*************************************************
Function:tcp 服务端和客户端总接口,多线程实现一个服务端处理多个客户端通信服务
author:zyh
date:2020.4
**************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>//提供IP地址转换函数
#include <sys/types.h>//数据类型定义文件
#include <sys/socket.h>//提供socket函数及数结构
#include <netinet/in.h>//定义数据结构体sockaddr_in
#include <netinet/ip.h>
#include <pthread.h>
#include <stdbool.h>

/**
函数功能:tcp创建socket通信
入参:无
出参:无
返回:成功:socket通信句柄,失败:-1
**/
int tcp_creat_socket(void)
{
	int sockfd = 0;
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (0 > sockfd) {
		perror("socket");
		return -1;
	}
	
	//设置一下参数属性,防止服务端重启,出现地址占用问题
	int bReuseaddr = 1;//允许重用本地地址和端口, close socket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket
	if(0 > setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(int))) {
		perror("setsockopt");
	}
	
#if 0
	int bDontLinger = 0;//如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:
	if(0 > setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&bDontLinger, sizeof(int))) {
		perror("setsockopt");
	}
#endif
	
#if 0
	// 接收缓冲区
	int nRecvBuf = 32*1024;//设置为32K
	setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));
	//发送缓冲区
	int nSendBuf = 32*1024;//设置为32K
	setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));	
#endif

	return sockfd;
}

/**
函数功能:tcp客户端连接服务器
入参:socket:socket通信句柄
入参:server_ip:服务器ip
入参:server_port:服务器端口(提供给客户端连接的端口)
出参:无
返回:成功:0, 失败:-1
**/
int tcp_client_connect(int sockfd, char *server_ip, int server_port)
{
	unsigned int server_addr = 0;
	struct sockaddr_in st_server_addr = {0};

	st_server_addr.sin_family = AF_INET;
	st_server_addr.sin_port = htons(server_port);//端口号,无符号短整型数值转换为网络字节序,即大端模式(big-endian)
	inet_pton(AF_INET, server_ip, &server_addr);//ip转换函数,主机字节序转化为网络字节序
	st_server_addr.sin_addr.s_addr = server_addr;
	
	if (0 > connect(sockfd, (struct sockaddr *)&st_server_addr, sizeof(st_server_addr))) {
		perror("connect");
		return -1;
	}
	
	return 0;
}

/**
函数功能:tcp发送消息
入参:sockfd:句柄
入参:sendBuf:发送的消息内容;
入参:len:发送的消息内容长度(字节)(如果使用strlen计算长度时请注意碰到0x00会截至)
出参:无
返回:成功:实际发送的字节数,失败:-1
**/
int tcp_send(int sockfd,  void *sendBuf,  int len)
{
	int sendbytes = 0;

	if (0 > (sendbytes = send(sockfd, sendBuf, len,  MSG_DONTWAIT|MSG_NOSIGNAL))) {
		perror("send");
		return -1;
	}
	return sendbytes;
}

/**
函数功能:tcp堵塞接收消息
入参:sockfd:文件操作句柄
入参:recvBuf:接收的消息缓冲区(使用前后注意清空消息缓冲区,要不然存放消息会遗留上次接收的部分数据)
入参:len:缓冲区长度
出参:无
返回:成功:实际接收的字节数(其中:如果连接已中止,返回0), 失败:-1
**/
int tcp_blocking_rcv(int sockfd, void *recvBuf, int len)
{
	int recvbytes = 0;

	if (0 > (recvbytes = recv(sockfd, recvBuf, len, 0)) ) {
		perror("recv");
		return -1;
	}
	
	return recvbytes;
}

/**
函数功能:tcp非堵塞接收消息
入参:sockfd:句柄
入参:recvBuf:接收的消息缓冲区(使用前后注意清空消息缓冲区,要不然存放消息会遗留上次接收的部分数据)
入参:len:缓冲区长度
入参:timeval_sec:超时时间(秒)
入参:timeval_usec:超时时间(微秒)
出参:无
返回:成功:实际接收的字节数(其中:如果连接已中止,返回0), 失败:-1,  超时:-2
**/
int tcp_noblocking_rcv(int sockfd,  void *recvBuf, int len, int timeval_sec, int timeval_usec)
{
	fd_set readset;
	struct timeval timeout={0, 0};
	int maxfd = 0;
	int recvbytes = 0;
	int ret = 0;
	
	timeout.tv_sec = timeval_sec;
	timeout.tv_usec = timeval_usec;
	FD_ZERO(&readset);           
	FD_SET(sockfd, &readset);         

	maxfd = sockfd + 1;    

	ret = select(maxfd, &readset, NULL, NULL, &timeout); 
	if (0 > ret) {
		return -2;
	} else {
		if (FD_ISSET(sockfd, &readset)) {
			if (0 > (recvbytes = recv(sockfd, recvBuf, len, MSG_DONTWAIT))) {
				perror("recv");
				return -1;
			}
		} else {
			return -1;
		}
	}
	
	return recvbytes;
}

/**
函数功能:tcp关闭sockfd通信句柄
入参:sockfd:socket通信句柄
出参:无
返回:无
**/
void tcp_close(int sockfd)
{
	//close(sockfd);
	if (sockfd > 0) {  //sockfd等于0时不能关,防止把文件句柄0关掉,影响系统,会导致scanf()函数输入不了
		close(sockfd);
	}
}


/*********************以下是服务端多出来的部分********************************************************************************************/
/**
函数功能:tcp服务器绑定端口、监听设置
入参:sockfd:socket通信句柄
入参:server_ip:服务器本地IP
入参:server_port:服务器本地端口(提供给客户端连接的端口)
入参:max_listen_num:最大监听客户端的数目
出参:无
返回:成功返回0, 失败返回-1
**/
int tcp_server_bind_and_listen(int sockfd, char *server_ip, int server_port, int max_listen_num)
{
	unsigned int server_addr = 0;
	struct sockaddr_in st_LocalAddr = {0}; //本地地址信息结构图,下面有具体的属性赋值
	
	st_LocalAddr.sin_family = AF_INET;  //该属性表示接收本机或其他机器传输
	st_LocalAddr.sin_port = htons(server_port); //端口号,无符号短整型数值转换为网络字节序,即大端模式(big-endian)
	inet_pton(AF_INET, server_ip, &server_addr);//ip转换函数,主机字节序转化为网络字节序
	st_LocalAddr.sin_addr.s_addr = server_addr;
	
	//绑定地址结构体和socket
	if(0 > bind(sockfd, (struct sockaddr *)&st_LocalAddr, sizeof(st_LocalAddr))) {
		perror("bind");
		return -1;
	}
 
	//开启监听 ,第二个参数是最大监听数
	if(0 > listen(sockfd, max_listen_num)) {
		perror("listen");
		return -1;
	}
	
	return 0;
}

/**
函数功能:tcp阻塞等待客户端连接
入参:sockfd:socket通信句柄;
出参:无
返回:成功:与客户端连接后的新句柄,失败:-1
**/
int tcp_server_wait_connect(int sockfd)
{
	int new_sockfd = 0;//建立连接后的句柄

	struct sockaddr_in st_RemoteAddr = {0}; //对方地址信息
 	socklen_t socklen = 0;  
	
	//在这里阻塞直到接收到连接,参数分别是socket句柄,接收到的地址信息以及大小 
	new_sockfd = accept(sockfd, (struct sockaddr *)&st_RemoteAddr, &socklen);
	if(0 > new_sockfd) {
		perror("accept");
		return -1;
	}
	
	return new_sockfd;
}


/**
函数功能:服务端每接收到新的客户端连接,就创建新线程提供服务
入参:new_sockfd:客户端连接上服务端后产生的新socket句柄
入参:callBackFun:处理客户端消息的回调函数
出参:无
返回:无
**/
void tcp_server_creat_pthread_process_client(int *new_sockfd, void* (*callBackFun)(void*))
{
	pthread_t thread_id;
	int ret = 0;
	
	pthread_create(&thread_id, NULL, callBackFun, (void *)new_sockfd);
	pthread_detach(thread_id);//将线程分离, 线程结束后自动释放线程资源,后续不需要使用pthread_join()进行回收
}

//callBackFun:处理客户端消息的回调函数,示例
void *tcp_server_callBackFun_demo(void *ptr)
{
	//int new_sockfd = (int *)ptr;//错误,不能直接使用地址,防止外部地址数值改变
	int new_sockfd = *(int *)ptr;
	printf("新建线程处理客户端服务(new_sockfd=%d)\n", new_sockfd);
	
	char recv_buff[1024] = {0};
	int recv_len = 0;
	
	char *str = NULL;
	
	while (1) {
		memset(recv_buff, 0, sizeof(recv_buff));
		
		recv_len = tcp_blocking_rcv(new_sockfd, recv_buff, sizeof(recv_buff));//堵塞接收消息
		if(0 > recv_len) {
			printf("接收客户端消息失败(new_sockfd=%d)!\n", new_sockfd);
			break;
		} else if(0 == recv_len) {
			printf("客户端断开连接(new_sockfd=%d)\n", new_sockfd);
			break;
		} else {
			printf("接收客户端消息(new_sockfd=%d):%s\n", new_sockfd, recv_buff);
			str = (char *)"服务端已收到";
			tcp_send(new_sockfd, str, strlen(str));
		}
		//usleep(1*1000);
	}
	
	tcp_close(new_sockfd);
	
	printf("退出线程服务(new_sockfd=%d)\n", new_sockfd);
	return NULL;
}

4、客户端通信main_client_demo.c

/*************************************************
Function:tcp 客户端进程,服务器中可运行多个
author:zyh
date:2020.4
**************************************************/
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include"tcp_spi.h"


int sockfd = -1;//客户端socket通信句柄
int tcp_client_connectflag = 0;//客户端socket通信连接标志


//开启一个接收消息的线程
void *fun_client_rcv(void *ptr)
{
	char recvBuf[1024] = {0};
	int recvBytes = 0;
	
	while (1) {
		if (1 == tcp_client_connectflag) {
			//堵塞接收
			memset(recvBuf, 0, sizeof(recvBuf));//清空
			recvBytes = tcp_blocking_rcv(sockfd, recvBuf, sizeof(recvBuf));//堵塞接收
			if (0 > recvBytes) {//接收失败
				printf("接收失败\n");
				tcp_client_connectflag = 0;
			} else if (0 == recvBytes) {//断开了连接
				printf("已断开连接\n");
				tcp_client_connectflag = 0;
			} else {
				printf("接收到消息:%s\n", recvBuf);
			}
		} else {
			sleep(1);
		}
	}
	
	return NULL;
}

//开启一个发送消息的线程
void *fun_client_send(void *ptr)
{
	char msg_buf[1024] = {0};
	
	while (1) {
		if (1 == tcp_client_connectflag) {//连接成功
			printf("\n请输入要发送的消息:\n");
			scanf("%s", msg_buf);
			printf("正在发送\n");
			if (0 > tcp_send(sockfd, msg_buf, strlen(msg_buf))) {//如果含有0x00不能用strlen
				printf("发送失败...!\n");
				tcp_client_connectflag = 0;
			} else {
				printf("发送成功\n");
			}
			sleep(1);
		} else {
			sleep(1);
		}
	}
	
	return NULL;
}


int main(int argc, char *argv[])
{
	char server_ip[16] = {0};//服务器IP
	int server_port = 0;//服务器端口
	int ret = 0;
	
	pthread_t thread_client_rcv, thread_client_send;

	//创建一个接收消息线程
	ret = pthread_create(&thread_client_rcv, NULL, fun_client_rcv, NULL);
	if (ret < 0) {
		printf("creat thread_client_rcv is fail!\n");
		return -1;
	}
	
	ret = pthread_create(&thread_client_send, NULL, fun_client_send, NULL);
	if (ret < 0) {
		printf("creat fun_client_send is fail!\n");
		return -1;
	}
		
	printf("请输入服务器ip:\n");
	scanf("%s", server_ip);
	
	printf("请输入服务器端口:\n");
	scanf("%d", &server_port);

	while (1) {
		if (0 == tcp_client_connectflag) {//未连接就不断中断重连
	
			if (sockfd > 0) {  //sockfd等于0时不能关,防止把文件句柄0关掉,导致scanf()函数输入不了
				tcp_close(sockfd);
			}
			
			sockfd = tcp_creat_socket();//创建socket
			if (0 > sockfd) {
				printf("socket创建失败...!\n");
				sleep(2);
				continue;
			}
			
			printf("请求连接...\n");
			if (0 > tcp_client_connect(sockfd, server_ip, server_port)) {
				printf("连接失败...重连中...\n");
				sleep(2);
				continue;
			} else {
				tcp_client_connectflag = 1;
				printf("连接成功!\n");
			}	
		} else {
			sleep(1);
		}
	}
	
	tcp_close(sockfd);
	pthread_join(thread_client_rcv, NULL);
	pthread_join(thread_client_send, NULL);
	return 0;
}

5、服务端通信main_server_demo.c

/*************************************************
Function:tcp 服务端进程,服务器中运行只一个
author:zyh
date:2020.4
**************************************************/
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include"tcp_spi.h"

void *tcp_server_callBackFun(void *ptr)
{
	//int new_sockfd = (int *)ptr;//错误,不能直接使用地址,防止外部地址数值改变
	int new_sockfd = *(int *)ptr;
	
	printf("开启线程服务处理客户端(new_sockfd=%d)\n", new_sockfd);
	
	char recv_buff[1024] = {0};
	int recv_len = 0;
	
	char *str = NULL;
	
	while (1) {
		memset(recv_buff, 0, sizeof(recv_buff));
		
		recv_len = tcp_blocking_rcv(new_sockfd, recv_buff, sizeof(recv_buff));//堵塞接收消息
		if(0 > recv_len) {
			printf("接收客户端消息失败(new_sockfd=%d)!\n", new_sockfd);
			break;
		} else if(0 == recv_len) {
			printf("客户端断开连接(new_sockfd=%d)\n", new_sockfd);
			break;
		} else {
			printf("收到客户端消息(new_sockfd=%d):%s\n", new_sockfd, recv_buff);
			str = (char *)"服务端已收到";
			tcp_send(new_sockfd, str, strlen(str));
		}
		//usleep(1*1000);
	}
	
	tcp_close(new_sockfd);
	
	printf("退出线程服务(new_sockfd=%d)\n", new_sockfd);
	return NULL;
}



int main(int argc, char *argv[])
{
	int ret = 0;

	int sockfd = -1;
	sockfd = tcp_creat_socket();//创建socket
	if (0 > sockfd) {
		printf("socket创建失败...!\n");
		return -1;
	}
	
	int port = 2022;
	char *ip = (char *)"127.0.0.1";
	
	ret = tcp_server_bind_and_listen(sockfd, ip, port, 1024);
	if (0 > ret) {
		printf("bind_and_listen失败...!\n");
		tcp_close(sockfd);
		return -1;
	}
	printf("服务端ip=localHost, 端口=%d\n", port);
	
	int new_sockfd = -1;
	while (1) {
		if (0 > (new_sockfd = tcp_server_wait_connect(sockfd))) {//堵塞直到客户端连接
			printf("等待连接失败...!\n");
			continue;
		} else {
			printf("\n有客户端连接成功! new_sockfd=%d\n", new_sockfd);
			tcp_server_creat_pthread_process_client(&new_sockfd, tcp_server_callBackFun);//服务端每接收到新的客户端连接,就创建新线程提供服务
		}
	}
	
	tcp_close(sockfd);

	return 0;
}

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

超详细c语言简化tcp通信接口(多线程实现一个服务端处理多个客户端服务) 的相关文章

  • 离散数学:主范式(主析取范式、主合取范式)

    求解主析取范式 主合取范式方法 1 真值表法 在表中列出变元值的全部可能 查表判断命题 命题结果真 xff0c 变元值对应主析取范式 命题结果假 xff0c 变元值对应主合取范式 2 等值演算法 命题化简 蕴涵等值式 xff1a A B A
  • Camera:双摄基本原理

    基本概念 基线 xff1a 两镜头的间距 景深 xff1a 画面清晰范围 xff0c 景深小 浅 背景虚化 xff0c 景深大背景清晰 影响景深的三个因素 xff1a 光圈 xff08 反比 xff0c 光圈越大景深越小 xff09 焦距
  • Linux:Hello World 模块

    前言 Linux 系统为应用程序提供了功能强大且容易扩展的 API xff0c 但在某些情况下 xff0c 这还远远不够 与硬件交互或进行需要访问系统中特权信息的操作时 xff0c 就需要一个内核模块 下面从 Hello World 模块来
  • 基础算法题 —— 计算字符串的编辑距离(动态规划)

    题解 在题目所求的编辑距离是指字符串 a 转换成字符串 b 所需最小的操作步骤 a i 61 b j 时 xff0c 要使 a i 61 61 b j 可使用的操作步骤如下 xff1a a i 可替换成 b j 字符串 a 下标为 i 的位
  • Matlab —— 02 基本操作与矩阵输入

    一 基本操作 1 help 功能 xff1a 便于快速了解指令的使用 ex 查询 pi 的简明介绍 Question 通过 matlab 计算出下列算式结果 Answer 1 2 或 xff08 3 xff09 xff08 4 xff09
  • Matlab —— 03结构化程式与自定义函数

    Script writing 新建脚本编辑界面 编辑测试文档 运行节 将整个框架划分为多个小节运行 xff0c 便于进行 Debug 设置断点 检查变量数值 方法一 xff1a 工作区内检查 方法二 xff1a 鼠标滑到变量位置 Struc
  • [unity] NavMesh 寻路 贴边走的问题 优化。

    NavMesh 寻路出来后 xff0c 角色走路很多时候贴着地图的边缘走 xff0c 很别扭 网上找了一个类似的问题 xff1a http www manew com thread 94163 1 1 html 里面方案 也挺适合我们的情况
  • 网易云ncm文件转mp3

    本人卖了一个ipod nano6 xff0c 帮买家导些歌 xff0c 结果用网易云下下来一堆ncm文件 xff0c 一脸懵逼 xff0c 因为ipod只能放mp3文件 上网查了一下ncm文件 xff0c 只能在会员有效期内放这个歌 于是上
  • catkin_make编译时fatal error: ###_msgs/***.h: 没有那个文件或目录

    h是头文件 xff0c 头文件 xff0c 就是一些定义和声明 xff0c 注意是定义 xff08 算是API接口吧 xff09 xff0c 编译时先加载这些头文件 xff0c 加载好了后主程序才能调用这些定义 那出现这种错误就是编译该程序
  • Theta* : 基于网格的任意角度寻路

    原文地址 xff08 科学上网 xff09 xff1a https arxiv org ftp arxiv papers 1401 1401 3843 pdf 1 简介 在本文中 xff0c 我们将研究一种机器人技术或视频游戏中使用的路径规
  • deepsort之YOLO系列目标跟踪及其他功能

    文章目录 一 ID switch是什么 xff1f 二 deepsort框架二 deepsort需要的模型1 目标检测器2 目标跟踪器 一 ID switch是什么 xff1f 跟踪问题中最重要的就是数据关联 xff08 data asso
  • PX4软件在环仿真注意点

    注 xff1a 最新内容参考PX4 user guide 点击此处 PX4下载指定版本代码和刷固件的三种方式 点击此处 PX4sitl固件编译方法 点击此处 PX4开发指南 点击此处 PX4无人机仿真 Gazebo 点击此处 px4仿真 知
  • cmake:生成动态链接库并使用

    已知 库函数的源文件名字叫hello c xff0c 库函数的头文件名字叫hello h xff0c 生成的动态链接库函数的名称叫libhello so xff0c 目标是在 hello install文件夹下安装这个库 xff0c 以便后
  • 算法:皇后问题

    问题 国际象棋中的皇后 xff0c 可以横向 纵向 斜向移动 如何在一个NXN的棋盘上放置N个皇后 xff0c 使得任意两个皇后都不在同一条横线 竖线 斜线方向上 xff1f 举个栗子 xff0c 下图的绿色格子是一个皇后在棋盘上的 封锁范
  • OpenCV+Python二维码条形码识别

    先上源码 xff0c github地址 xff1a https github com DerrickRose25 Opencv QRcode recognition 环境 xff1a Pycharm Python3 7 在pycharm里安
  • Onvif协议:实现Probe命令来进行设备发现(discover)

    在onvif协议对接中 xff0c 首先要明确服务器和客户端的身份 服务器 xff1a 通常是你要对接的其他厂家的数字摄像头 xff08 IPC xff09 客户端 xff1a 通常是对接的ipc的设备程序 xff0c 安防业内多称 xff
  • Linux C/C++编程:Udp组播(多播)

    Udp多播简介 概叙 单播用于两个主机之间单对单的通信广播用于一个主机对整个局域网上所有主机上的数据通信单播和广播是两个极端 xff0c 要么对一个主机进行通信 xff0c 要么对整个局域网的主机进行通信实际情况下 xff0c 经常需要对一
  • cmake:同一目录下多个源文件

    此文为 xff1a 轻松入门cmake系列教程前文为 xff1a cmake xff1a Hello cmake 接下来进入稍微复杂的例子 xff1a 在同一个目录下有多个源文件 第一个实验 实践 在之前的目录下添加2个文件 xff0c t
  • cmake:string

    字符串操作 概要 Search span class token operator and span Replace span class token function string span span class token punctu
  • 性能:你知道并发用户数应该怎么算吗

    我们知道 xff0c 一个性能测试中 xff0c 往往会有各种各样的指标 xff0c 比如TPS RPS QPS HPS CPM等 我们在实际工作的时候 xff0c 应该对这些概念有统一的认识 建议使用TPS作为关键的性能指标 另外 xff

随机推荐

  • C/C++面试:手写智能指针类

    shared ptr原理 shared ptr实际上是对裸指针进行了一层封装 xff0c 成员变量除了裸指针之外 xff0c 还有一个引用计数 xff0c 它记录裸指针被引用的次数 xff08 有多少个shared ptr指向这同一个裸指针
  • golang:http.request

    request 表示由服务器接收或由客户端发送的HTTP请求 xff0c 例如客户端 client 在发送各种请求时 xff0c 需要先新建一个请求对象 xff0c 然后调用一些请求的方法开始自定义一些配置 xff0c 服务端监听到该请求便
  • git:smartgit

    下载安装smartgit 下载 xff1a https www syntevo com smartgit download 终端下操作 xff1a 执行命令 xff1a tar xvf smartgit tar gz 执行命令 xff1a
  • golang:如何在proto3中用上golang对应的interface{}类型

    首先 xff0c 我希望所有golang中用于http请求响应的结构 xff0c 都使用proto3来定义 麻烦的是 xff0c 有的情况下某个字段的类型可能是动态的 xff0c 对应的JSON类型可能是number string bool
  • 如何计算icmp校验和

    前几天看到大佬写的一篇关于icmp远控后门文章 xff0c 对icmp协议充满了激情 xff0c 通过查阅资料了解相关所需的知识 xff0c 实现整个程序首先要了解imcp包请求与回复 xff0c 在整个请求中最先就涉及到icmp包的构造
  • 作为一个自动化本科生到底应该学些什么(讲讲个人经历和感受)

    2019 6 26日深夜 晚上在床上准备休息 xff0c 一个同跟我聊天说自己大学荒废了 xff0c 突然有很多感想想写一写 我觉得自己大学也是得过且过地过着的 xff0c 不过虽然充满艰辛和不满意 xff0c 但还是挺充实的 先自我介绍一
  • 嵌入式项目实战——基于QT的视频监控系统设计(一)

    嵌入式项目实战 基于QT的视频监控系统设计 xff08 一 xff09 这个五一因为疫情 xff0c 只能待在家里 xff0c 想了想不如将我之前做的一个小的嵌入式的练习项目分享出来 xff0c 供入门嵌入式的同学们学习 基于QT的视频监控
  • 嵌入式项目实战——基于QT的视频监控系统设计(三)

    嵌入式项目实战 基于QT的视频监控系统设计 xff08 三 xff09 进入到五一假期第三天 xff0c 继续我们的项目 本来五一假期还是想好好休息一下的 xff0c 因为最近学习的状态不太好 xff0c 刷题都没有思路了 xff0c 但是
  • 嵌入式开发板RS485协议串口编程——角度传感器数据读取

    嵌入式开发板RS485协议串口编程 倾角传感器数据读取 之前分享过一篇嵌入式操作系统开发板中的串口编程 光敏电阻数据读取 xff0c 是基于TTL协议的串口编程 xff0c 本节主要讲述基于RS485协议的串口编程 xff0c 掌握了这两种
  • 嵌入式开发板CAN通信编程——伺服电机驱动

    嵌入式开发板CAN通信编程 伺服电机驱动 在实际的嵌入式项目开发过程中 xff0c 若不涉及上位机与开发板的通信传输数据 xff0c 那最关键的无非就是两个内容 xff0c 读取传感器的数据并处理 xff0c 驱动硬件设备工作 传感器数据的
  • 嵌入式字符设备驱动——ULN2003步进电机驱动程序实现

    嵌入式字符设备驱动 ULN2003步进电机驱动程序实现 之前分享了字符设备驱动程序的实现 hello驱动 xff0c 是不涉及硬件操作的 xff0c 我说过要给大家分享一篇涉及硬件操作的字符设备驱动程序的实现 xff0c 今天周末休息 xf
  • Linux多进程间通信——共享内存实现

    Linux多进程间通信 共享内存实现 又到了每周分享时刻 xff0c 这周我要分享的是关于Linux中进程间通信问题 xff0c 这对于底层程序的实现至关重要 xff0c 进程间通信方式主要包括管程 共享内存 消息传递 套接字这几种方式 x
  • 嵌入式开发板RS485多节点串口编程——关节力矩传感器数据读取

    嵌入式开发板RS485多节点串口编程 关节力矩传感器数据读取 最近学业繁忙 xff0c 主要是准备找工作 xff0c 有一段时间没分享了 xff0c 今天给大家分享一下我最近利用TI AM4376开发板RS485串口读取两个关节力矩传感器的
  • Linux多进程间通信——管道通信实现

    Linux多进程间通信 管道通信实现 之前分享了linux多进程间通信的两种方法 xff0c 套接字和共享内存通信 今天来分享一下另外一种多进程通信方法 管道 管道分为有名管道和无名管道 无名管道用于有亲缘关系之间的进程 xff0c 即父子
  • Linux多进程间通信——消息传递实现

    Linux多进程间通信 消息队列实现 之前已经分享了共享内存 管道 套接字来实现多进程的通信 xff0c 下面再介绍一下消息队列 xff0c 后面我还会再介绍最后一个多进程的通信方式 xff0c 通过信号来实现 xff0c 这样多进程通信的
  • RS485总线究竟能挂接多少个设备?

    N年前做门禁系统上位机软件开发的时候突击培训过串口通信编程基础 后来在我的脑海里一直认为RS485总线能且只能挂接256个设备 xff08 因为地址是1byte xff0c 取值范围也就0 255 xff09 后来经过几个项目的了解 xff
  • Python Raw Socket使用示例(发送TCP SYN数据包)

    python view plain copy import sys import time import socket import struct import random def SendPacketData Buffer 61 Non
  • mysql-server 依赖 mysql-server-5.5 解决方案

    问题 ubuntu14 04 3安装mysql时报错 xff1a sudo apt get install mysql server mysql client 正在读取软件包列表 完成 正在分析软件包的依赖关系树 正在读取状态信息 完成 有
  • 生成aruco码方法

    有两种方法得到想要的aruco码 xff1a 1 直接通过网址得到 http chev me arucogen xff08 不过只有四个格式 xff09 网页截图为 xff1a 2 通过运行C 43 43 代码得到 利用C 43 43 生成
  • 超详细c语言简化tcp通信接口(多线程实现一个服务端处理多个客户端服务)

    超详细c语言tcp通信接口 1 可下载源码 xff08 客户端 服务端通信 xff09 2 说明3 接口代码4 客户端通信main client demo c5 服务端通信main server demo c 1 可下载源码 xff08 客