当前位置: 首页 > news >正文

网络基础-----C语言经典题目(12)

一、MTU,IP 协议头中 TTL是什么?

        MTU 指的是网络层能够接收的最大数据包大小,单位为字节。主要作用是限制数据链路层一次能够传输的数据量。

        IP 协议头中的 TTL 是 IP 数据头部的一个 8 位字段,最初它的设计目的是限制数据包在网络中的生存空间,但现在它表示的是数据包能够经过的最大跳数。每经过一个路由器,TTL 的值就会减 1。当 TTL 的值变为 0 时。路由器会丢弃该数据包,并向源主机发送 ICMP 超时消息。

        TTL主要作用是防止数据包在网络中无限循环,避免网络拥塞。

        MTU 属于数据链路层概念,决定了数据包的最大物理传输大小。

        TTL 是网络层概念,控制着数据包的生存周期,主要与路由机制相关。

二、TCP,IP 协议头大小?以及常用字段有哪些?

TCP 协议头

        大小:最小尺寸为 20 字节,若包含选项字段,则会更大。

        常用字段:源端口、目的端口、序列号、确认号等。

IP 协议头

        大小:标准大小是 20 字节,但可以通过选项字段进行扩展。

        常用字段:版本、首部长度、服务类型、总长度等。

三、什么是 IO 多路复用?处理任务过程中与多线程有什么不同?

        IO 多路复用是一种能够同时对多个 IO 操作进行监控的机制,一旦有 IO 操作准备就绪(可读、可写、出现异常等),它就会发出通知。这一机制主要借助系统调用(select、poll、epoll)来达成,适用于高并发场景。

        IO 多路复用采用的是单线程轮询多个 IO 事件的工作模式。流程如下:

 1.把所有需要监控的 IO 描述符(select)都集合起来。

 2.调用多路复用函数,让线程处于阻塞状态,等待某一个或多个 IO 描述符变为就绪状态。

 3.当有 IO 操作准备好后,函数会返回,并告知具体是哪些 IO 描述符可以进行操作了。

 4.程序对这些就绪的 IO 描述符进行相应的处理。

区别:

对比维度IO多路复用多线程
线程数量单线程(少量线程)就能处理多个 IO每个 IO 操作或者连接都可能需要一个独立线程
系统开销小,只需进行轮询操作大,线程创建、切换、销毁
上下文切换只有在用户态进行轮询,没有内核态的上下文切换频繁进行内核态的上下文切换,消耗 CPU 
扩展性在处理大量长连接时,性能好随着线程数量增加,性能下降
编程难度复杂简单
适用场景IO 密集型且连接数很多单 IO 事件发送频率较低的场景CPU 密集型或 IO 操作比较耗时的场景

典型应用场景

        IO 多路复用:Web服务器,聊天服务器

        多线程:显示传感器数据,发送传感器数据

IO 多路复用(select)实现:

#define MAX_CLIENTS 10  // 最大客户端连接数
#define BUFFER_SIZE 1024  // 缓冲区大小int main() 
{int server_fd, client_fd;  // 服务器和客户端套接字描述符struct sockaddr_in server_addr, client_addr;  // 服务器和客户端地址结构socklen_t client_addr_len = sizeof(client_addr);  // 客户端地址长度fd_set readfds;  // 文件描述符集合,用于select监控int max_fd;  // 最大文件描述符值int client_fds[MAX_CLIENTS];  // 客户端套接字描述符数组char buffer[BUFFER_SIZE];  // 数据缓冲区// 创建TCP套接字server_fd = socket(AF_INET, SOCK_STREAM, 0);if (server_fd == -1) {perror("socket failed");exit(EXIT_FAILURE);}// 设置套接字选项,允许地址重用int opt = 1;if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {perror("setsockopt failed");exit(EXIT_FAILURE);}// 配置服务器地址结构memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;  // 监听所有可用接口server_addr.sin_port = htons(8080);  // 监听端口8080// 绑定套接字到指定地址和端口if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)         {perror("bind failed");exit(EXIT_FAILURE);}// 开始监听连接,队列长度为5if (listen(server_fd, 5) == -1) {perror("listen failed");exit(EXIT_FAILURE);}// 初始化客户端套接字数组,-1表示空闲for (int i = 0; i < MAX_CLIENTS; i++) {client_fds[i] = -1;}printf("Server started, listening on port 8080...\n");// 主事件循环while (1) {// 清空文件描述符集合FD_ZERO(&readfds);// 将服务器套接字添加到监控集合FD_SET(server_fd, &readfds);max_fd = server_fd;  // 初始化最大文件描述符// 将所有活跃客户端套接字添加到监控集合for (int i = 0; i < MAX_CLIENTS; i++)     {if (client_fds[i] > 0) {FD_SET(client_fds[i], &readfds);}if (client_fds[i] > max_fd) {max_fd = client_fds[i];  // 更新最大文件描述符}}// 阻塞等待,直到有文件描述符就绪int activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);if (activity == -1) {perror("select failed");exit(EXIT_FAILURE);}// 处理新连接请求if (FD_ISSET(server_fd, &readfds)) {client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);if (client_fd == -1) {perror("accept failed");continue;}printf("New connection, socket fd: %d, IP: %s, Port: %d\n",client_fd, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));// 将新客户端添加到客户端数组for (int i = 0; i < MAX_CLIENTS; i++) {if (client_fds[i] == -1) {client_fds[i] = client_fd;break;}}}// 处理客户端数据for (int i = 0; i < MAX_CLIENTS; i++) {if (client_fds[i] > 0 && FD_ISSET(client_fds[i], &readfds)) {memset(buffer, 0, BUFFER_SIZE);int valread = read(client_fds[i], buffer, BUFFER_SIZE);if (valread <= 0) {// 客户端关闭连接(valread=0)或发生错误(valread=-1)printf("Client disconnected, socket fd: %d\n", client_fds[i]);close(client_fds[i]);client_fds[i] = -1;  // 标记为空闲} else {// 回显数据给客户端send(client_fds[i], buffer, strlen(buffer), 0);}}}}return 0;
}

多线程实现:

#define BUFFER_SIZE 1024  // 缓冲区大小// 线程处理函数,用于处理客户端连接
void *handle_client(void *arg) 
{int client_fd = *(int *)arg;  // 获取客户端套接字描述符char buffer[BUFFER_SIZE];int valread;// 循环读取客户端数据while ((valread = read(client_fd, buffer, BUFFER_SIZE)) > 0) {// 回显数据给客户端send(client_fd, buffer, valread, 0);memset(buffer, 0, BUFFER_SIZE);  // 清空缓冲区}printf("Client disconnected, socket fd: %d\n", client_fd);close(client_fd);  // 关闭客户端套接字free(arg);  // 释放动态分配的内存pthread_exit(NULL);  // 退出线程
}int main() 
{int server_fd, client_fd;  // 服务器和客户端套接字描述符struct sockaddr_in server_addr, client_addr;  // 服务器和客户端地址结构socklen_t client_addr_len = sizeof(client_addr);  // 客户端地址长度pthread_t thread_id;  // 线程ID// 创建TCP套接字server_fd = socket(AF_INET, SOCK_STREAM, 0);if (server_fd == -1) {perror("socket failed");exit(EXIT_FAILURE);}// 设置套接字选项,允许地址重用int opt = 1;if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {perror("setsockopt failed");exit(EXIT_FAILURE);}// 配置服务器地址结构memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;  // 监听所有可用接口server_addr.sin_port = htons(8080);  // 监听端口8080// 绑定套接字到指定地址和端口if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)     {perror("bind failed");exit(EXIT_FAILURE);}// 开始监听连接,队列长度为5if (listen(server_fd, 5) == -1) {perror("listen failed");exit(EXIT_FAILURE);}printf("Server started, listening on port 8080...\n");// 主循环,接受新连接while (1) {// 接受新连接client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);if (client_fd == -1) {perror("accept failed");continue;}printf("New connection, socket fd: %d, IP: %s, Port: %d\n",client_fd, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));// 为每个客户端创建一个新线程int *new_client_fd = malloc(sizeof(int));  // 动态分配内存存储客户端套接字描述符*new_client_fd = client_fd;// 创建线程并传递客户端套接字描述符if (pthread_create(&thread_id, NULL, handle_client, (void *)new_client_fd) != 0) {perror("pthread_create failed");free(new_client_fd);  // 释放内存close(client_fd);  // 关闭客户端套接字}// 分离线程,使其结束时自动释放资源pthread_detach(thread_id);}close(server_fd);  // 关闭服务器套接字(实际上不会执行到这里)return 0;
}

四、服务器 / 客户端模型有哪些?c/s,b/s 模型的区别

服务器 / 客户端模型

   1.迭代服务器

        迭代服务器每次仅能处理一个客户端请求。当它在处理某个客户端请求时,其他客户端必须等待,直到当前请求处理完毕。

   2.并发服务器

        并发服务器能够同时处理多个客户端请求,响应速度快,资源消耗大。

   3.基于事件驱动的服务器

        事件驱动服务器借助 IO 多路复用技术(select、poll、epoll)来同时监听多个文件描述符的状态变化。

C/S与B/S 模型的区别

   1.客户端类型

        C/S 模型:客户端是专门开发的应用程序,需要用户手动安装,如QQ客户端等。

        B/S 模型:客户端是浏览器,用户无需安装额外的软件,如淘宝、百度。

   2.通信协议

        C/S 模型:客户端和服务器之间可以使用自定义的协议,像 TCP、UDP 等。

        B/S 模型:客户端和服务器之间使用标准的 HTTP 或 HTTPS 协议进行通信。

   3.部署与维护

        C/S 模型:客户端和服务器都需要进行部署,而且客户端的升级需要用户手动更新,维护成本相对较高。

        B/S 模型:只需部署服务器端,客户使用浏览器即可。

   4.安全性

        C/S 模型:客户端是自定义的,开发者可以对数据传输和存储进行更精细的控制,安全性较高。

        B/S 模型:使用标准的 HTTP 协议,数据在传输过程中容易被截获,需要加密,如 HTTPS。

五、服务器并发模型有哪些?

1.多进程模型

        为每个客户端连接都创建一个子进程进行处理。各个进程相互隔离,一个进程崩溃不会影响其他进程。创建进程的开销较大。

2.多线程模型

        为每个客户端连接创建一个线程来处理。线程创建的开销比较小,但线程间共享资源容易引发竞争问题。

3.IO 多路复用模型

        借助单个进程监听多个文件描述符,从而实现并发处理。资源消耗少,能处理大量连接。

4.事件驱动模型

        基于事件循环机制,在有时间发生时调用回调函数进行处理,资源利用率高。

六、linux 中 I/O 模型有哪些?如何给文件设置非阻塞?

1.阻塞 I/O

        在执行 I/O 操作时,进程会被挂起,一直等到操作完成才继续执行后续任务。像调用read()write()这类函数时,若没有数据可读或者无法立即写入,进程就会被阻塞。

2.非阻塞 I/O

        当进程发起 I/O 操作后,无论是否有数据可读或可写时,系统都会立即返回结果,不会让进程陷入等待状态。进程需要通过轮询的方式不断检查 I/O 状态,以此来确定操作是否完成。

3.I/O 多路复用

        借助 selectpollepoll等系统调用,进程能够同时监视多个文件描述符的 I/O 事件。当其中有文件描述符就绪时,进程会收到通知,然后再进行相应的 I/O 操作。

4.信号驱动 I/O

        进程可以通过 sigaction 系统调用注册一个信号处理函数,当 I/O 事件就绪时,系统会发送 SIGIO 信号给进程,进程在信号处理函数中 执行 I/O 操作。

5.异步 I/O

        进程通过aio_readaio_write 等函数发起异步 I/O 请求,系统会在 I/O 操作完成后通知进程,在这个过程中,进程无需等待操作完成,可以继续执行其他任务。

设置文件为非阻塞模式

   1.使用 fcntl 函数获取当前文件状态标志。

   2.把 O_NONBLOCK 标志添加到获取的文件状态标志中。

   3.再次使用 fcntl 函数将修改后的文件状态标志设置回文件描述符。

int main() 
{// 打开终端设备文件,以只读模式打开int fd = open("/dev/tty", O_RDONLY);if (fd == -1) {perror("open");  // 打印打开文件失败的错误信息return 1;        // 程序异常退出}// 获取当前文件描述符的状态标志// F_GETFL是fcntl的命令,用于获取文件状态标志int flags = fcntl(fd, F_GETFL, 0);if (flags == -1) {perror("fcntl"); // 打印获取标志失败的错误信息close(fd);       // 关闭文件描述符return 1;        // 程序异常退出}// 在现有标志上添加O_NONBLOCK标志// 使用按位或运算,确保不影响其他已有的标志位flags |= O_NONBLOCK;// 设置修改后的文件状态标志// F_SETFL是fcntl的命令,用于设置文件状态标志if (fcntl(fd, F_SETFL, flags) == -1) {perror("fcntl"); // 打印设置标志失败的错误信息close(fd);       // 关闭文件描述符return 1;        // 程序异常退出}// 现在文件描述符已设置为非阻塞模式// 执行读取操作,无论是否有数据都会立即返回char buffer[100];int n = read(fd, buffer, sizeof(buffer));// 检查读取结果if (n == -1) {// EAGAIN或EWOULDBLOCK错误表示当前没有数据可读// 这是非阻塞I/O的正常情况if (errno == EAGAIN || errno == EWOULDBLOCK) {printf("没有数据可读\n");} else {// 其他错误表示真正的读取失败perror("read");}} else {// 成功读取到数据,打印读取的字节数和内容printf("读取了 %d 字节: %.*s\n", n, n, buffer);}// 关闭文件描述符,释放系统资源close(fd);return 0;
}

七、select 和 epoll 的区别?应用层是如何使用的?

特性selectepoll
最大文件描述符限制受限于 FD_SETSIZE(1024)无限制
数据结构使用位图存储文件描述符红黑树和链表
事件通知机制水平触发水平触发、边缘触发
内存拷贝每次调用需重复从用户空间拷贝数据使用内核事件表,仅需一次拷贝
时间复杂度O(n),需遍历所有文件描述符O(1),仅遍历就绪的文件描述符
应用场景连接数少且就绪率高连接数多且活跃度地

应用层示例:

1.select

int main() 
{fd_set readfds;struct timeval timeout;int max_fd, ret;// 初始化文件描述符集合FD_ZERO(&readfds);FD_SET(0, &readfds);  // 监听标准输入(fd=0)max_fd = 0;// 设置超时时间timeout.tv_sec = 5;timeout.tv_usec = 0;// 调用selectret = select(max_fd + 1, &readfds, NULL, NULL, &timeout);if (ret < 0) {perror("select error");exit(EXIT_FAILURE);} else if (ret == 0) {printf("Timeout occurred!\n");} else {// 检查哪些文件描述符就绪if (FD_ISSET(0, &readfds)) {printf("Standard input is readable.\n");// 处理输入...}}return 0;
}

2.epoll

#define MAX_EVENTS 10int main() 
{int epfd, nfds;struct epoll_event ev, events[MAX_EVENTS];// 创建epoll实例epfd = epoll_create1(0);if (epfd == -1) {perror("epoll_create1");exit(EXIT_FAILURE);}// 注册标准输入(fd=0)到epollev.events = EPOLLIN;  // 监听读事件ev.data.fd = 0;if (epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &ev) == -1) {perror("epoll_ctl: add");exit(EXIT_FAILURE);}// 等待事件发生nfds = epoll_wait(epfd, events, MAX_EVENTS, -1);if (nfds == -1) {perror("epoll_wait");exit(EXIT_FAILURE);}// 处理就绪事件for (int i = 0; i < nfds; i++) {if (events[i].data.fd == 0) {printf("Standard input is readable.\n");// 处理输入...}}close(epfd);return 0;
}

八、HTTP 协议的应用,哪一层的协议?默认端口是什么?

        HTTP 协议处于应用层,默认端口号是 80。主要功能是在 Web 浏览器和 Web 服务器之间传输超文本。而C语言本身不直接支持 HTTP 协议,不过可以借助套接字来实现 HTTP 客户端或服务器。

        

#define PORT 80
#define BUFFER_SIZE 1024int main() {int sockfd;struct sockaddr_in server_addr;char request[BUFFER_SIZE];char response[BUFFER_SIZE];// 创建套接字sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}// 设置服务器地址memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(PORT);// 将IPv4地址从文本转换为二进制形式if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) {perror("invalid address/ address not supported");exit(EXIT_FAILURE);}// 连接到服务器if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("connection failed");exit(EXIT_FAILURE);}// 构建HTTP请求sprintf(request, "GET / HTTP/1.1\r\n""Host: example.com\r\n""Connection: close\r\n""\r\n");// 发送HTTP请求send(sockfd, request, strlen(request), 0);// 接收HTTP响应memset(response, 0, BUFFER_SIZE);ssize_t bytes_received = recv(sockfd, response, BUFFER_SIZE - 1, 0);if (bytes_received > 0) {printf("Response:\n%s\n", response);}// 关闭套接字close(sockfd);return 0;
}

九、HTTP 如何交互(服务器和客户端交互一次的过程)

服务器端

   1.创建套接字:socket()函数来创建一个套接字。

   2.绑定地址:bind()函数,把套接字和指定 IP 地址以及端口(一般是 80 )绑定在一起。

   3.监听连接:listen()函数,让服务器进入监听状态,等待客户端的连接请求。

   4.接受连接:accept()函数接受客户端的连接,进而获取客户端套接字。

   5.接收 HTTP 请求:recv()函数,从客户端套接字读取请求数据。

   6.解析请求:对 HTTP 请求行(方法、路径、版本)以及头部字段进行解析。

   7.处理请求:按照请求的路径和方法,准备号响应的响应内容。

   8.发送 HTTP 响应:send()函数,把响应头和响应体通过客户端套接字发送出去。

   9.关闭连接:响应发送完毕后,关闭客户端套接字。

客户端

   1.创建套接字:socket()。

   2.连接服务器:connect()函数,连接到服务器的 IP 地址和端口。

   3.构造 HTTP 请求:按照 HTTP 协议格式,构建请求行、头部字段以及请求体。

   4.发送请求:send()函数,通过套接字将请求数据发生出去。

   5.接收响应:recv()函数,从套接字读取服务器返回的响应数据。

   6.解析响应:对响应状态码、头部字段以及响应体进行解析。

   7.处理数据:依据响应内容,对数据进行相应的处理。

   8.关闭套接字:数据处理完成后,关闭套接字。

十、HTTP 请求行的组成,有哪些请求方式?状态码有哪些?

        HTTP 请求行是 HTTP 请求的首个部分,组成结构为:请求方法、请求 URI 以及 HTTP 版本,用空格分割,行末已 \r\n 结束。

请求方式:

   1.GET:用于请求获取指定资源。

   2.POST:用于向服务器提交数据,常被用于表单提交或者上传文件。

   3.HEAD:和 GET 方法类型,但服务器只返回响应头,不会返回响应体。

PUT、DELETE、OPTIONS、TRACE、CONNECT。

状态码分类:

   1. 1xx(信息性状态码):表示请求已被接收,需要继续处理。

   2. 2xx(成功状态码):表示请求已成功被服务器接收、理解并处理。

   3. 3xx(重定向状态码):表示需要客户端采取进一步的操作来完成请求。

   4. 4xx(客户端错误状态码):表示客户端可能存在错误,导致请求无法被完成。

        404:请求的资源不存在。

   5. 5xx(服务器错误状态码):表示服务器在处理请求的过程中发生了错误。

十一、HTTP 长连接和短连接的区别?

连接方式:

        短连接:客户端与服务器没进行一次 HTTP 操作,就建立一次连接,任务完成后立即断开连接。这意味着每次请求都要经历“连接 - 请求 - 响应 - 关闭”的过程。

        长连接:在一次连接建立之后,客户端和服务器之间可以在这条连接上进行多次请求和响应的交互,直到一方主动关闭连接。

实现差异:

        短连接:每次发送 HTTP 请求前创建 socket 连接,请求处理完毕后关闭 socket。

        长连接:需要在 HTTP 请求头中添加 Connection:keep-alive 字段,以此告知服务器保持连接。

效率对比:

        短连接:每次请求都要进行 TCP 的三次握手和四次挥手,效率较低,开销较大。

        长连接:效率高,但会一直占用服务器资源。

适用场景:

        短连接:静态网页的访问。

        长连接:实时数据推送、电商网站、购物车等操作。

十二、HTTP 中 URL 的作用?

1.资源定位

        URL 的核心功能是明确网络上资源的具体位置。它就像一个地址,能让客户端清楚直到要访问的资源位于何处,例如 http://example.com/path/file.html 。指出了资源所在的服务器是 example.com ,路径为 /ptah/file.html。

2.协议指定

        URL 会明确访问资源所采用的协议,如 HTTP、HTTPS、FTP 等。

3.服务器信息提供

        URL 包含了服务器的域名或者 IP 地址,以及端口号(默认情况下,HTTP 为80,HTTPS 为 443)

十三、Web 服务器是如何搭建的?

1.创建套接字并监听连接

        创建套接字,绑定到指定端口,开始监听客户端的连接请求。

#define PORT 8080int main() 
{int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[1024] = {0};const char *hello = "HTTP/1.1 200 OK\nContent-Type: text/plain\n\nHello, World!";// 创建套接字文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 设置套接字选项if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定套接字到指定地址和端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 监听连接if (listen(server_fd, 3) < 0) {perror("listen");exit(EXIT_FAILURE);}printf("服务器监听在端口 %d...\n", PORT);

2.接受客户端连接

        用一个循环持续接受客户端连接,为每个新连接创建一个新的套接字。

    while(1) {// 接受客户端连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");exit(EXIT_FAILURE);}// 读取客户端请求int valread = read(new_socket, buffer, 1024);printf("客户端请求:\n%s\n", buffer);

3.解析 HTTP 请求

        // 解析请求方法和路径char method[10], path[100];sscanf(buffer, "%s %s", method, path);

4.处理请求并返回

        // 准备响应const char *response;if (strcmp(path, "/") == 0) {response = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n""<html><body><h1>Welcome to my server!</h1></body></html>";} else if (strcmp(path, "/about") == 0) {response = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n""<html><body><h1>About</h1><p>This is a simple C web server.</p></body></html>";} else     {response = "HTTP/1.1 404 Not Found\nContent-Type: text/html\n\n""<html><body><h1>404 Not Found</h1></body></html>";}// 发送HTTP响应send(new_socket, response, strlen(response), 0);printf("响应已发送\n");

5.关闭连接

        // 关闭套接字close(new_socket);}return 0;
}

十四、在线商城信息查询系统中,并发服务器的并发量是多少?用什么工具进行测试?并发服务器的响应速度是多少?

        并发量是100,测试工具用的 ab,简单查询的话,响应速度在 100ms以内。

相关文章:

网络基础-----C语言经典题目(12)

一、MTU&#xff0c;IP 协议头中 TTL是什么&#xff1f; MTU 指的是网络层能够接收的最大数据包大小&#xff0c;单位为字节。主要作用是限制数据链路层一次能够传输的数据量。 IP 协议头中的 TTL 是 IP 数据头部的一个 8 位字段&#xff0c;最初它的设计目的是限制数据包在网络…...

【第十六届蓝桥杯省赛】比赛心得与经验分享(PythonA 组)

文章目录 一、我的成绩二、我的备赛经历三、如何备赛&#xff08;个人观点&#xff09;1. 基础语法2. 数据结构3. 算法4. 数学 四、做题技巧与注意事项五、我的题解试题A 偏蓝 &#x1f3c6;100%试题B IPV6 &#x1f3c6;0%试题C 2025图形 &#x1f3c6;100%试题D 最大数字 &am…...

解决Maven项目中报错“java不支持版本6即更高的版本 7”

错误背景 当Maven项目编译或运行时出现错误提示 Java不支持版本6即更高的版本7&#xff0c;通常是由于项目配置的JDK版本与当前环境或编译器设置不一致导致的。例如&#xff1a; 项目配置的Java版本为6或7&#xff0c;但实际使用的是JDK 17。Maven或IDE的编译器未正确指定目标…...

MySQL--索引入门

MySQL官方对索引的定义为&#xff1a;索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构。 Mysql在存储数据之外&#xff0c;数据库系统各种还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种引用&#xff08;指向&#xff09;表中的数据…...

【网络原理】深入理解HTTPS协议

本篇博客给大家带来的是网络原理的知识点, 由于时间有限, 分三天来写, 本篇为线程第三篇,也是最后一篇. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动…...

利用Elixir中的原子特性 + 错误消息泄露 -- Atom Bomb

题目信息: This new atom bomb early warning system is quite strange… 题目使用 elixir 语言 一开始,我们会访问 /page.html <!DOCTYPE html> <!-- 设定文档语言为英语 --> <html lang"en"> <head><!-- 设定字符编码为UTF-8 --><…...

机器人--STM32

STM32启动模式 1,从主闪存存储启动器启动(默认) 2,从系统存储启动器启动 下载程序时需要使用的启动方式。 3&#xff0c;从内置的SRAM启动...

LVGL -文本显示 英文、中文

1 文本 在 LVGL 中,文本控件(Label)是一种基本的 UI 组件,用于显示文本信息。文本控件可以用于各种场景,如显示状态信息、提示消息、标题等。在图形用户界面(GUI)开发中,文本是传达信息和指导用户的重要组成部分。为了有效地展示文本,以下是与文本相关的几个关键方面…...

Java面试资源获取

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 **1. GitHub开源项目****2. 技术博客与社区*…...

探索 Spring AI 的 ChatClient API:构建智能对话应用的利器

探索 Spring AI 的 ChatClient API&#xff1a;构建智能对话应用的利器 前言 在当今人工智能蓬勃发展的时代&#xff0c;智能对话系统成为了众多应用的核心组成部分。无论是客服机器人、智能助手还是聊天应用&#xff0c;都离不开高效、灵活的对话处理能力。Spring AI 作为 S…...

Java大师成长计划之第11天:Java Memory Model与Volatile关键字

&#x1f4e2; 友情提示&#xff1a; 本文由银河易创AI&#xff08;https://ai.eaigx.com&#xff09;平台gpt-4o-mini模型辅助创作完成&#xff0c;旨在提供灵感参考与技术分享&#xff0c;文中关键数据、代码与结论建议通过官方渠道验证。 在多线程编程中&#xff0c;线程的执…...

java学习之数据结构:一、数组

主要是对数组所有的东西进行总结&#xff0c;整理 适合小白~ 目录 1.什么是数组 1.1数组定义 1.2数组创建 1&#xff09;静态创建 2&#xff09;动态创建 1.3数组遍历 1&#xff09;for和while遍历 2&#xff09;foreach遍历 2.数组越界问题及解决 2.1数组越界问题 2…...

Oracle OCP认证考试考点详解083系列04

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 16. 第16题&#xff1a; 题目 解析及答案&#xff1a; 关于使用恢复管理器&#xff08;RMAN&#xff09;恢复表&#xff0c;以下哪三项是…...

MARM:推荐系统中的记忆增强突破

文章目录 1. 背景1.1 模型规模与推荐系统的挑战1.2 缓存技术在推荐系统中的潜力1.3 推荐系统中的数据与计算需求1.4 复杂度对比1.5 MARM模型的创新性 2. 方法2.1 流程2.1.1 序列生成器2.1.2 外部缓存查找2.1.3 多目标注意力机制2.1.4 发结果到缓存 **2.2 MARM与SIM**2.2.1 SIM的…...

INP指标

什么是INP&#xff08;Interaction to Next Paint&#xff09; 参考网站&#xff1a;webVital-INP文档 定义与核心目标 INP 是一项稳定的 Core Web Vitals 指标&#xff0c;通过统计用户访问期间所有符合条件的互动约定时间&#xff0c;评估网页对用户操作的总体响应能力。最…...

Flink 的状态机制

在实时流处理领域&#xff0c;状态管理是构建复杂业务逻辑的核心能力。Apache Flink 通过统一的状态抽象和高效的容错机制&#xff0c;为开发者提供了从毫秒级窗口聚合到 TB 级历史数据关联的全场景支持。本文将深入剖析 Flink 状态机制的底层原理&#xff0c;结合实际案例展示…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】1.1 数据库核心概念与PostgreSQL技术优势

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 深度解析PostgreSQL核心架构与技术优势&#xff1a;从数据库原理到实战场景1.1 数据库核心概念与PostgreSQL技术优势1.1.1 关系型数据库核心架构解析1.1.1.1 数据库系统的底…...

linux下,ollama会把模型文件保存在哪里?

文章目录 运行ollama,有两种形式,估计得分开讨论首先是使用自动启动的ollama:先跑个“小一点的大模型”但是现在模型文件存在哪儿呢?运行ollama,有两种形式,估计得分开讨论 我们用两种方式,来运行ollama。 首先是使用自动启动的ollama: ps -aux | grep ollama系统自…...

EMMC存储性能测试方法

记于 2022 年 9 月 15 日 EMMC存储性能测试方法 - Wesley’s Blog 参考Android-emmc性能测试 | 一叶知秋进行实践操作 dd 命令 页面缓存 为了测试 emmc 的真实读写性能&#xff0c;我们需要先把页面缓存给清理&#xff1a; echo 1 > /proc/sys/vm/drop_caches console:…...

19. LangChain安全与伦理:如何避免模型“幻觉“与数据泄露?

引言&#xff1a;当AI成为企业"数字员工"时的责任边界 2025年某金融机构因AI客服泄露用户信用卡信息被罚款2300万美元。本文将基于LangChain的安全架构与Deepseek-R1的合规实践&#xff0c;揭示如何构建既强大又安全的AI系统。 一、AI安全风险矩阵 1.1 2025年最新威…...

5月3日日记

上午睡到自然醒&#xff08;其实六点多被我爸叫起来抢火车票&#xff0c;发现明天中午的软卧候补上了&#xff0c;挺好的&#xff09;然后继续睡到快10点。 中午吃的什么来着&#xff0c;好像是西红柿炒鸡蛋和藜麦饭&#xff0c;有个鱼不是很想吃就没吃 中午打了两把吃鸡&…...

C++类_构造函数

在 C11 里&#xff0c;类的构造函数有多种类型&#xff0c;下面为你详细介绍各类构造函数并给出示例代码。 1. 默认构造函数 默认构造函数是没有参数的构造函数&#xff0c;要是没有为类定义任何构造函数&#xff0c;编译器会自动生成一个默认构造函数。 2. 带参数的构造函数…...

【React】Hooks useReducer 详解,让状态管理更可预测、更高效

1.背景 useReducer是React提供的一个高级Hook,没有它我们也可以正常开发&#xff0c;但是useReducer可以使我们的代码具有更好的可读性&#xff0c;可维护性。 useReducer 跟 useState 一样的都是帮我们管理组件的状态的&#xff0c;但是呢与useState不同的是 useReducer 是集…...

Runnable组件重试机制降低程序错误率

一、LangChain 重试机制深度解析 当构建生产级AI应用时&#xff0c;with_retry() 机制可有效提升系统容错性&#xff0c;典型应用场景包括&#xff1a; API调用频率限制时的自动恢复模型服务临时不可用的故障转移网络波动导致的瞬时异常处理 参数详解与配置策略 1. 参数配置…...

纹理过滤方式和纹理包裹方式

纹理过滤方式 纹理过滤方式有临近过滤&#xff08;Nearest&#xff09;和双线性插值过滤&#xff08;Linear&#xff09;&#xff0c;什么时候用什么过滤方式其实看个人选择&#xff0c;区别就是临近过滤是当需要的像素大于图片像素时候&#xff0c;一些像素点需要复用与他相近…...

55.[前端开发-前端工程化]Day02-包管理工具npm等

包管理工具详解 npm、yarn、cnpm、npx、pnpm 1 npm包管理工具 代码共享方案 包管理工具npm 2 package配置文件 npm的配置文件 方式二 常见的配置文件 常见的属性 常见的属性 常见的属性 依赖的版本管理 常见属性 npm install 命令 项目安装 3 npm install原理 npm instal…...

Maven安装配置以及Idea中的配置教程

一、下载Maven 我使用的是3.9.9的版本&#xff1a; 下载地址&#xff1a;Download Apache Maven – Maven 二、安装 将下载好的Maven压缩包解压到一个路径不包含中文的文件夹&#xff1a; 三、配置环境变量 以win11系统为例&#xff1a; 1.鼠标右键此电脑->属性->…...

【JavaScript】性能优化:打造高效前端应用

文章目录 一、执行效率优化(关键路径优化)1.1 算法时间复杂度控制1.2 Web Workers多线程计算二、内存管理(避免内存泄漏)2.1 定时器清理2.2 DOM引用释放三、DOM操作优化(渲染性能)3.1 批量DOM更新3.2 读写分离策略四、网络传输优化(加载性能)4.1 代码分割(Dynamic Imp…...

【C语言练习】018. 定义和初始化结构体

018. 定义和初始化结构体 018. 定义和初始化结构体1. 定义结构体示例1:定义一个简单的结构体输出结果2. 初始化结构体示例2:在声明时初始化结构体输出结果示例3:使用指定初始化器初始化结构体(C99及以上标准支持)输出结果3. 结构体数组示例4:定义和初始化结构体数组输出结…...

Three.js支持模型格式区别、建议

在 Three.js 中,3D 模型的种类和格式非常多样,每种格式都有其适用场景和优缺点。以下是常见的 Three.js 支持的模型格式、它们的区别、使用建议及推荐。 在这里推荐免费的blender工具,免费、占用空间不大,而且好用,前端打开模型时使用不错,或者有自己想做的模型也可以用它…...

JavaScript基础-流程控制概念

在JavaScript编程中&#xff0c;掌握如何控制程序的执行流程是编写功能强大、逻辑清晰代码的关键。流程控制语句允许我们根据不同的条件执行不同的代码块&#xff0c;或者重复执行某些操作&#xff0c;从而实现复杂的功能逻辑。本文将详细介绍JavaScript中的几种主要流程控制结…...

PowerBI企业运营分析——多维度日期指标分析

PowerBI企业运营分析——多维度日期指标分析 欢迎来到Powerbi小课堂&#xff0c;在竞争激烈的市场环境中&#xff0c;企业运营分析平台成为提升竞争力的核心工具。 通过整合多源数据、实时监控关键指标&#xff0c;该平台能够精准分析业务表现&#xff0c;快速识别问题与机会…...

施磊老师rpc(三)

文章目录 mprpc框架项目动态库编译框架生成动态库框架初始化函数-文件读取1. 为什么要传入 argc, argv2. 读取参数逻辑3. 配置文件设计 init部分实现 mprpc配置文件加载(一)配置文件加载类成员变量主要方法**src/include/mprpcconfig.h** 配置文件**bin/test.conf** 实现配置文…...

k8s 探针

Kubernetes 中的探针&#xff08;Probes&#xff09;用于检测容器的健康状态或就绪状态&#xff0c;确保应用在运行时的可靠性。Kubernetes 提供三种探针类型&#xff0c;它们的核心区别在于用途和失败后的处理逻辑。以下是它们的详细说明和对比&#xff1a; 1. 启动探针&…...

MIT6.S081-lab8

MIT6.S081-lab8 1. Large files 从 lecture 我们可以知道&#xff0c;我们目前的单个文件的最大大小很小&#xff0c;这是因为我们能够索引的索引块范围很小&#xff0c;实际上&#xff0c;目前的索引只有直接索引和一级索引&#xff0c;而这个实验就是需要我们去实现二级索引…...

【RabbitMQ】 RabbitMQ快速上手

文章目录 一、RabbitMQ 核心概念1.1 Producer和Consumer2.2 Connection和Channel2.3 Virtual host2.4 Queue2.5 Exchange2.6 RabbitMQ工作流程 二、AMQP协议三 、web界面操作4.1 用户相关操作4.2 虚拟主机相关操作 四、RabbitMQ快速入门4.1 引入依赖4.2 编写生产者代码4.2.1 创…...

使用Rust + WebAssembly提升前端渲染性能:从原理到落地

一、问题背景&#xff1a;为什么选择WebAssembly&#xff1f; 最近在开发数据可视化大屏项目时&#xff0c;我们遇到了一个棘手的问题&#xff1a;前端需要实时渲染10万数据点的动态散点图&#xff0c;使用纯JavaScript Canvas方案在低端设备上帧率不足15FPS。经过性能分析&a…...

【quantity】9 长度单位模块(length.rs)

代码是用Rust语言定义的一组长度单位类型&#xff0c;利用了泛型和类型别名来创建带不同SI前缀的长度量。下面是详细解释&#xff1a; 基础结构&#xff1a; 使用了Quantity<V, P, Meter>作为基础类型&#xff0c;表示一个带有值类型V、前缀P和单位Meter的量。 Meter是…...

网络通信领域的基础或流行协议

一、TCP(传输控制协议) 1. 宏观介绍 TCP:全称“Transmission Control Protocol”——传输控制协议,是互联网最基础的传输协议之一。传输层协议,提供面向连接、可靠的字节流传输服务。它通过三次握手建立连接、四次挥手断开连接,确保数据有序、完整地传输作用:让两个设备…...

STM32——GPIO

1、GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 可配置为8种输入输出模式 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 …...

AE模板 300个故障干扰损坏字幕条标题动画视频转场预设

这个AE模板提供了300个故障干扰损坏字幕条标题动画视频转场预设&#xff0c;让您的视频具有炫酷的故障效果。无论是预告片、宣传片还是其他类型的视频&#xff0c;这个模板都能带给您令人惊叹的故障运动标题效果。该模板无需任何外置插件或脚本&#xff0c;只需一键点击即可应用…...

2025-2026 XCPC

基本信息 本赛季由 jr-zlw \texttt{\color{#AA00AA}{jr-zlw}} jr-zlw, Skyzhou \texttt{\color{#03A89E} Skyzhou} Skyzhou 和 sunchaoyi \texttt{\color{#0000FF}sunchaoyi} sunchaoyi 组队&#xff0c;全靠大佬带飞~。 训练记录 2025.05.02 The 2023 Guangdong Provinci…...

list类的详细讲解

【本节目标】 1. list的介绍及使用 2. list的深度剖析及模拟实现 3. list与vector的对比 1. list的介绍及使用 1.1 list的介绍 1. list 是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list 的底层是双向链表结构&a…...

中小企业MES系统数据库设计

版本&#xff1a;V1.0 日期&#xff1a;2025年5月2日 一、数据库架构概览 1.1 数据库选型 数据类型数据库类型技术选型用途时序数据&#xff08;传感器读数&#xff09;时序数据库TimescaleDB存储设备实时监控数据结构化业务数据关系型数据库PostgreSQL工单、质量、设备等核心…...

wfp CommandParameter 详细解说

WPF 中的 CommandParameter 是命令模型中的关键属性,用于向命令的执行逻辑传递动态参数。以下是其主要特性和应用场景的详细解析: 1. ‌基本概念与用法‌ ‌数据传递机制‌ CommandParameter 通常与 Command 属性配合使用,允许在 XAML 中静态定义参数或在绑定中动态传递值。…...

正弦波、方波、三角波和锯齿波信号发生器——Multisim电路仿真

目录 Multisim使用教程说明链接 一、正弦波信号发生电路 1.1正弦波发生电路 电路组成 工作原理 振荡频率 1.2 正弦波发生电路仿真分析 工程文件链接 二、方波信号发生电路 2.1 方波发生电路可调频率 工作原理 详细过程 2.2 方波发生电路可调频率/可调占空比 调节占空比 方波产生…...

Java语言概述

Java语言概述 什么是程序&#xff1f; ​ 程序是计算机执行某些操作或解决某个问题而编写的一系列有序指令单集合。 ​ 举例&#xff1a; ​ 计算11&#xff0c;并把结果写在黑板上 ​ 计算11&#xff0c;并把结果显示在屏幕上&#xff08;按编程语言规定的语句&#xff0…...

截图软件、画图软件、左右分屏插件、快捷键

截图软件 画图软件 画图时候按字母可以改变颜色&#xff1a;红色r,蓝色b,绿色g,粉色p,橙色o 左右分屏&#xff1a; 快捷键 1.打开文件或文件夹&#xff1a; CtrlP&#xff1a;快速打开文件。CtrlR&#xff1a;快速打开文件或文件夹。 2.文件操作&#xff1a; CtrlN&…...

Linux 信号

一、生活中的信号 1.1、生活中的信号从产生到结束过程 例&#xff1a; ①、外卖电话响了&#xff08;信号产生&#xff09;-> 我接了电话并告诉外卖员说先放到楼下的架子上&#xff08;识别到这个信号&#xff0c;并记住&#xff0c;保存到我的脑海里面&#xff09; ->…...

AI 生成内容的版权困境:法律、技术与伦理的三重挑战

最近研学过程中发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…...