Linux-TCP并发模型相关函数接口-014

2024-03-11 21:44

本文主要是介绍Linux-TCP并发模型相关函数接口-014,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1【TCP】多线程模型

相关函数接口已在前面章节介绍,这里不再赘述

源码示例(1):

//【client.c】
int CreateTcpClient(char *pip, int port)
{int ret = 0;int sockfd = 0;struct sockaddr_in seraddr;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(port);seraddr.sin_addr.s_addr = inet_addr(pip);ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (-1 == ret){perror("fail to connect");return -1;}return sockfd;
}int main(void)
{int sockfd = 0;char tmpbuff[4096] = {"hello world"};int cnt = 0;ssize_t nsize = 0;sockfd = CreateTcpClient("192.168.1.183", 50000);while (1){memset(tmpbuff, 0, sizeof(tmpbuff));sprintf(tmpbuff, "hello world --- %d", cnt);cnt++;nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);if (-1 == nsize){perror("fail to send");return -1;}memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0);if (-1 == nsize){perror("fail to recv");return -1;}printf("RECV:%s\n", tmpbuff);}close(sockfd);return 0;
}//【server.c】
int CreateListenSocket(char *pip, int port)
{int ret = 0;int sockfd = 0;struct sockaddr_in seraddr;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(port);seraddr.sin_addr.s_addr = inet_addr(pip);ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (-1 == ret){perror("fail to bind");return -1;}ret = listen(sockfd, 10);if (-1 == ret){perror("fail to listen");return -1;}return sockfd;
}void *HandleTcpClient(void *arg)
{char tmpbuff[4096] = {0};ssize_t nsize = 0;int confd = arg;while (1){memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0);if (-1 == nsize){perror("fail to recv");return NULL;}else if (0 == nsize){return NULL;}sprintf(tmpbuff, "%s ----echo", tmpbuff);nsize = send(confd, tmpbuff, strlen(tmpbuff), 0);if (-1 == nsize){perror("fail to send");return NULL;}}return NULL;
}int main(void)
{int sockfd = 0;int confd = 0;pthread_t tid;pthread_attr_t attr;sockfd = CreateListenSocket("192.168.1.183", 50000);pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);while (1){confd = accept(sockfd, NULL, NULL);if (-1 == confd){perror("fail to accept");return -1;}pthread_create(&tid, &attr, HandleTcpClient, confd);}close(sockfd);return 0;
}

2【IO】模型

2.1阻塞IO

相关函数接口已在前面章节介绍,这里不再赘述

2.2非阻塞IO

源码示例(1):

//【write.c】
int main(void)
{int fd = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_WRONLY);if (-1 == fd){perror("fail to open");return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}//【read.c】
int main(void)
{int fd = 0;int flags = 0;char *pret = NULL;ssize_t nsize = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_RDONLY);if (-1 == fd){perror("fail to open");return -1;}flags = fcntl(fd, F_GETFL);flags |= O_NONBLOCK;fcntl(fd, F_SETFL, flags);flags = fcntl(0, F_GETFL);flags |= O_NONBLOCK;fcntl(0, F_SETFL, flags);while (1){memset(tmpbuff, 0, sizeof(tmpbuff));pret = gets(tmpbuff);if (pret != NULL){printf("STDIN:%s\n", tmpbuff);}memset(tmpbuff, 0, sizeof(tmpbuff));nsize = read(fd, tmpbuff, sizeof(tmpbuff));if (nsize > 0){printf("FIFO:%s\n", tmpbuff);}}close(fd);return 0;
}

2.3异步IO

源码示例(1):

//【write.c】
int main(void)
{int fd = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_WRONLY);if (-1 == fd){perror("fail to open");return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}//【read.c】
int fd = 0;void handler(int signo)
{char tmpbuff[4096] = {0};ssize_t nsize = 0;memset(tmpbuff, 0, sizeof(tmpbuff));nsize = read(fd, tmpbuff, sizeof(tmpbuff));if (nsize > 0){printf("FIFO:%s\n", tmpbuff);}return;
}int main(void)
{int flags = 0;char *pret = NULL;ssize_t nsize = 0;char tmpbuff[4096] = {0};signal(SIGIO, handler);mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_RDONLY);if (-1 == fd){perror("fail to open");return -1;}flags = fcntl(fd, F_GETFL);flags |= O_ASYNC;fcntl(fd, F_SETFL, flags);fcntl(fd, F_SETOWN, getpid());while (1){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf("STDIN:%s\n", tmpbuff);}close(fd);
}

2.4多路复用IO

2.4.1【select】

2.4.1.1函数原型
【int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);】
2.4.1.2函数功能
监听文件描述符集合中是否有文件描述编程ready状态
2.4.1.3函数参数
1.【nfds】:最大文件描述符的值+1 
2.【readfds】:读文件描述符集合
3.【writefds】:写文件描述符集合
4.【exceptfds】:其余文件描述符集合
5.【timeout】:等待的时长【NULL】:表示一直等待
2.4.1.4返回值
【成功】:返回文件描述符集合中的文件描述符个数
【失败】:返回【-1】
2.4.1.5常用的几个函数

1.【FD_CLR】

(1)函数原型:【void FD_CLR(int fd, fd_set *set);】
(2)函数功能: 将文件描述符fd从集合中清除 
(3)函数参数:【fd】:【set】:

(4)返回值:

2.【FD_ISSET】

(1)函数原型:【int  FD_ISSET(int fd, fd_set *set);】
(2)函数功能: 判断文件描述符fd是否仍在集合中
(3)函数参数:【fd】:【set】:
(4)返回值:

3.【FD_SET】

(1)函数原型:【int  FD_ISSET(int fd, fd_set *set);】
(2)函数功能: 将文件描述符fd加入到集合中
(3)函数参数:【fd】:【set】:
(4)返回值:

4.【FD_ZERO】

(1)函数原型:【int  FD_ISSET(int fd, fd_set *set);】
(2)函数功能: 将文件描述符集合清0
(3)函数参数:
【set】:
(4)返回值:

源码示例(1):

//【write.c】
int main(void)
{int fd = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_WRONLY);if (-1 == fd){perror("fail to open");return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}//【read.c】
int main(void)
{int fd = 0;int flags = 0;char *pret = NULL;ssize_t nsize = 0;char tmpbuff[4096] = {0};fd_set rdfds;fd_set tmpfds;int ret = 0;mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_RDONLY);if (-1 == fd){perror("fail to open");return -1;}FD_ZERO(&rdfds);FD_SET(fd, &rdfds);FD_SET(0, &rdfds);while (1){tmpfds = rdfds;ret = select(fd+1, &tmpfds, NULL, NULL, NULL);if (-1 == ret){perror("fail to select");return -1;}if (FD_ISSET(fd, &tmpfds)){memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf("FIFO:%s\n", tmpbuff);}if (FD_ISSET(0, &tmpfds)){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf("STDIN:%s\n", tmpbuff);}}close(fd);return 0;
}

源码示例(2):

//【client.c】
int CreateTcpClient(char *pip, int port)
{int ret = 0;int sockfd = 0;struct sockaddr_in seraddr;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(port);seraddr.sin_addr.s_addr = inet_addr(pip);ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (-1 == ret){perror("fail to connect");return -1;}return sockfd;
}int main(void)
{int sockfd = 0;char tmpbuff[4096] = {"hello world"};int cnt = 0;ssize_t nsize = 0;sockfd = CreateTcpClient("192.168.1.183", 50000);while (1){memset(tmpbuff, 0, sizeof(tmpbuff));sprintf(tmpbuff, "hello world --- %d", cnt);cnt++;nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);if (-1 == nsize){perror("fail to send");return -1;}memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0);if (-1 == nsize){perror("fail to recv");return -1;}printf("RECV:%s\n", tmpbuff);}close(sockfd);return 0;
}//【server.c】
int CreateListenSocket(char *pip, int port)
{int ret = 0;int sockfd = 0;struct sockaddr_in seraddr;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(port);seraddr.sin_addr.s_addr = inet_addr(pip);ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (-1 == ret){perror("fail to bind");return -1;}ret = listen(sockfd, 10);if (-1 == ret){perror("fail to listen");return -1;}return sockfd;
}int HandleTcpClient(int confd)
{char tmpbuff[4096] = {0};ssize_t nsize = 0;memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0);if (-1 == nsize){perror("fail to recv");return -1;}else if (0 == nsize){return 0;}sprintf(tmpbuff, "%s ----echo", tmpbuff);nsize = send(confd, tmpbuff, strlen(tmpbuff), 0);if (-1 == nsize){perror("fail to send");return -1;}return nsize;
}int main(void)
{int sockfd = 0;int confd = 0;fd_set rdfds;fd_set tmpfds;int maxfd = 0;int ret = 0;int i = 0;sockfd = CreateListenSocket("192.168.1.183", 50000);FD_ZERO(&rdfds);FD_SET(sockfd, &rdfds);maxfd = sockfd;while (1){tmpfds = rdfds;ret = select(maxfd+1, &tmpfds, NULL, NULL, NULL);if (-1 == ret){perror("fail to select");return -1;}if (FD_ISSET(sockfd, &tmpfds)){confd = accept(sockfd, NULL, NULL);if (-1 == confd){perror("fail to accept");FD_CLR(sockfd, &rdfds);close(sockfd);continue;}FD_SET(confd, &rdfds);maxfd = maxfd > confd ? maxfd : confd;}for (i = sockfd+1; i <= maxfd; i++){if (FD_ISSET(i, &tmpfds)){ret = HandleTcpClient(i);if (-1 == ret){fprintf(stderr, "handle client failed!\n");FD_CLR(i, &rdfds);close(i);continue;}else if (0 == ret){fprintf(stderr, "client disconnected!\n");FD_CLR(i, &rdfds);close(i);continue;}}}}close(confd);close(sockfd);return 0;
}

2.4.2【poll】

2.4.2.1函数原型
【int poll(struct pollfd *fds, nfds_t nfds, int timeout);】
2.4.2.2函数功能
监听文件描述符集合是否有事件发生
2.4.2.3函数参数
1.【fds】:监听文件描述符集合数组空间首地址
2.【nfds】:监听文件描述符集合元素个数
3.【timeout】:等待的时间【-1】: 一直等待

结构体说明:

struct pollfd {int   fd;/* file descriptor 监听的文件描述符*/short events;/* requested events 要监听的事件*/short revents;/* returned events 实际产生的事件*/
};
//结构体成员介绍
fd:监听的文件描述符
events:要监听的事件  POLLIN:是否可读  POLLOUT:是否可写
revents:实际产生的事件 
2.4.2.4返回值
【成功】:返回产生事件的文件描述符个数
【失败】:返回【-1】

源码示例(1):

//【write.c】
int main(void)
{int fd = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_WRONLY);if (-1 == fd){perror("fail to open");return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}//【read.c】
int main(void)
{int fd = 0;int flags = 0;char *pret = NULL;ssize_t nsize = 0;char tmpbuff[4096] = {0};struct pollfd fds[2];int nready = 0;mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_RDONLY);if (-1 == fd){perror("fail to open");return -1;}fds[0].fd = fd;fds[0].events = POLLIN;fds[1].fd = 0;fds[1].events = POLLIN;while (1){nready = poll(fds, 2, -1);if (-1 == nready){perror("fail to poll");return -1;}if (fds[0].revents & POLLIN){memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf("FIFO:%s\n", tmpbuff);}if (fds[1].revents & POLLIN){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf("STDIN:%s\n", tmpbuff);}}close(fd);
}

源码示例(2):

//【client.c】
int CreateTcpClient(char *pip, int port)
{int ret = 0;int sockfd = 0;struct sockaddr_in seraddr;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(port);seraddr.sin_addr.s_addr = inet_addr(pip);ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (-1 == ret){perror("fail to connect");return -1;}return sockfd;
}int main(void)
{int sockfd = 0;char tmpbuff[4096] = {"hello world"};int cnt = 0;ssize_t nsize = 0;sockfd = CreateTcpClient("192.168.1.183", 50000);while (1){memset(tmpbuff, 0, sizeof(tmpbuff));sprintf(tmpbuff, "hello world --- %d", cnt);cnt++;nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);if (-1 == nsize){perror("fail to send");return -1;}memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0);if (-1 == nsize){perror("fail to recv");return -1;}printf("RECV:%s\n", tmpbuff);}close(sockfd);return 0;
}//【server.c】
int CreateListenSocket(char *pip, int port)
{int ret = 0;int sockfd = 0;struct sockaddr_in seraddr;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(port);seraddr.sin_addr.s_addr = inet_addr(pip);ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (-1 == ret){perror("fail to bind");return -1;}ret = listen(sockfd, 10);if (-1 == ret){perror("fail to listen");return -1;}return sockfd;
}int HandleTcpClient(int confd)
{char tmpbuff[4096] = {0};ssize_t nsize = 0;memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0);if (-1 == nsize){perror("fail to recv");return -1;}else if (0 == nsize){return 0;}sprintf(tmpbuff, "%s ----echo", tmpbuff);nsize = send(confd, tmpbuff, strlen(tmpbuff), 0);if (-1 == nsize){perror("fail to send");return -1;}return nsize;
}int InitFds(struct pollfd *fds, int maxlen)
{int i = 0;for (i = 0; i < maxlen; i++){fds[i].fd = -1;}return 0;
}int AddFd(struct pollfd *fds, int maxlen, int fd, short env)
{int i = 0;for (i = 0; i < maxlen; i++){if (fds[i].fd == -1){fds[i].fd = fd;fds[i].events = env;break;}}if (i == maxlen){return -1;}return 0;
}int DeleteFd(struct pollfd *fds, int maxlen, int fd)
{int i = 0;for (i = 0; i < maxlen; i++){if (fds[i].fd == fd){fds[i].fd = -1;break;}}return 0;
}int main(void)
{int sockfd = 0;int confd = 0;struct pollfd fds[1024];int nready = 0;int i = 0;int ret = 0;sockfd = CreateListenSocket("192.168.1.183", 50000);InitFds(fds, 1024);AddFd(fds, 1024, sockfd, POLLIN);while (1){nready = poll(fds, 1024, -1);if (-1 == nready){perror("fail to poll");return -1;}for (i = 0; i < 1024; i++){if (fds[i].fd == -1){continue;}if (fds[i].revents & POLLIN && fds[i].fd == sockfd){confd = accept(sockfd, NULL, NULL);if (-1 == confd){perror("fail to accept");DeleteFd(fds, 1024, sockfd);close(sockfd);continue;}AddFd(fds, 1024, confd, POLLIN);}else if (fds[i].revents & POLLIN && fds[i].fd != sockfd){ret = HandleTcpClient(fds[i].fd);if (-1 == ret){fprintf(stderr, "handle tcp client failed!\n");close(fds[i].fd);DeleteFd(fds, 1024, fds[i].fd);continue;}else if (0 == ret){fprintf(stderr, "client disconnected!\n");close(fds[i].fd);DeleteFd(fds, 1024, fds[i].fd);continue;}}}}close(sockfd);return 0;
}

2.4.3【epoll】

2.4.3.1函数原型

【int epoll_create(int size);】

2.4.3.2函数功能
创建一张内核事件表
2.4.3.3函数参数
【size】:事件的个数
2.4.3.4返回值
【成功】:返回文件描述符
【失败】:返回【-1】

2.4.4【epoll_ctl】

2.4.4.1函数原型

【int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);】

2.4.4.2函数功能

维护epoll时间表

2.4.4.3函数参数
1.【epfd】:事件表的文件描述符
2.【op】:【EPOLL_CTL_ADD】:添加事件【EPOLL_CTL_MOD】:修改事件【EPOLL_CTL_DEL】:删除事件
3.【fd】:操作的文件描述符
4.【event】:事件对应的事件

结构体说明:

typedef union epoll_data {void        *ptr;int          fd;uint32_t     u32;uint64_t     u64;
} epoll_data_t;struct epoll_event {uint32_t     events;      /* Epoll events */epoll_data_t data;        /* User data variable */
};
2.4.4.4返回值
【成功】:返回【0】 
【失败】:返回【-1】

2.4.5【epoll_wait】

2.4.5.1函数原型
【int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);】
2.4.5.2函数功能
监听事件表中的事件
2.4.5.3函数参数
1.【epfd】:文件描述符
2.【events】:存放实际产生事件的数组空间首地址
3.【maxevents】:最多存放事件的个数
4.【timeout】:设定监听的时间(超过该时间则不再监听)【-1】:一直监听直到有事件发生
2.4.5.4返回值
【成功】:返回产生事件的文件描述符个数
【失败】:返回【-1】
【超时】:如果时间达到仍没有事件发生返回【0】

源码示例(1):

//【write.c】
int main(void)
{int fd = 0;char tmpbuff[4096] = {0};mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_WRONLY);if (-1 == fd){perror("fail to open");return -1;}while (1){gets(tmpbuff);write(fd, tmpbuff, strlen(tmpbuff));}close(fd);return 0;
}//【read.c】
int main(void)
{int fd = 0;int flags = 0;char *pret = NULL;ssize_t nsize = 0;char tmpbuff[4096] = {0};int epfd = 0;struct epoll_event env;struct epoll_event retenv[2];int nready = 0;int i = 0;mkfifo("/tmp/myfifo", 0664);fd = open("/tmp/myfifo", O_RDONLY);if (-1 == fd){perror("fail to open");return -1;}epfd = epoll_create(2);if (-1 == epfd){perror("fail to epoll_create");return -1;}env.events = EPOLLIN;env.data.fd = fd;epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &env);env.events = EPOLLIN;env.data.fd = 0;epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &env);while (1){nready = epoll_wait(epfd, retenv, 2, -1);if (-1 == nready){perror("fail to epoll_wait");return -1;}for (i = 0; i < nready; i++){if (retenv[i].data.fd == 0){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);printf("STDIN:%s\n", tmpbuff);}else if (retenv[i].data.fd == fd){memset(tmpbuff, 0, sizeof(tmpbuff));read(fd, tmpbuff, sizeof(tmpbuff));printf("FIFO:%s\n", tmpbuff);}}}close(fd);
}

源码示例(2):

这篇关于Linux-TCP并发模型相关函数接口-014的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/799174

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C