续|Linux网络编程:TCP协议核心解析与实战开发
在上一篇博客中我们掌握了UDP协议的核心特性与Linux网络编程实现UDP作为无连接、不可靠的传输协议适用于实时性要求高的场景。而TCPTransmission Control Protocol传输控制协议是传输层另一核心协议作为面向连接、可靠的流式传输协议是互联网中最常用的通信协议适用于对数据可靠性、顺序性要求高的场景如网页浏览、文件传输、即时通讯、数据库交互。本文将从TCP协议的核心特性出发详细讲解TCP的编程步骤、三次握手/四次挥手的连接机制、黏包问题及解决方案同时结合完整的代码示例实现Linux TCP网络编程让你彻底掌握这一核心网络技术。一、TCP协议的核心特性TCP与UDP是传输层的两大核心协议二者特性互补TCP的核心设计围绕可靠性和面向连接展开相比UDP增加了连接建立、数据确认、超时重传、拥塞控制等机制同时具备全双工通信能力其核心特性可总结为以下几点1. 面向连接TCP通信前客户端与服务端必须先通过三次握手建立专用的通信链路通信过程中持续维护连接状态通信结束后需通过四次挥手断开连接链路的建立和断开是TCP通信的前提。2. 可靠传输TCP通过应答机制、超时重传、拥塞控制、差错校验等机制保证数据可靠传输发送方发送数据后需等待接收方的ACK确认报文未收到则超时重传对传输的数据进行校验发现错误则丢弃并要求重传根据网络拥塞状态动态调整发送速率避免网络过载。3. 流式套接字TCP以字节流为单位传输数据数据无边界、连续传输这是与UDP面向数据报的核心区别发送方的发送次数与接收方的接收次数无需对应如发送2次接收1次数据在传输过程中是连续的字节序列接收方需自行处理数据的拆分与解析。4. 全双工通信TCP支持同一时刻双向数据传输客户端和服务端可同时发送和接收数据而UDP为半双工通信同一时刻仅能单向传输。5. 有序传输TCP会为每个字节的数据分配序列号接收方根据序列号对数据重新排序保证数据按发送顺序到达解决了UDP数据乱序的问题。6. 有读写阻塞TCP的发送和接收操作均存在阻塞读阻塞接收方无数据可读时recv函数会阻塞直到有数据到达写阻塞发送方的发送缓冲区满时send函数会阻塞直到缓冲区有空闲空间发送缓冲区默认大小为64K超出则触发写阻塞。7. 开销与延迟较高由于TCP需要维护连接状态、实现可靠传输机制相比UDP其网络开销更大、传输延迟更高这是为了可靠性付出的代价。二、TCP与UDP核心特性对比为了更清晰地理解TCP的适用场景我们将TCP与UDP的核心特性做直观对比方便实际开发中选型特性TCP传输控制协议UDP用户数据报协议连接性面向连接三次握手建立连接无连接传输可靠性可靠应答、重传、拥塞控制不可靠无确认、无重传数据传输单位字节流无边界、连续数据报有边界、独立通信方式全双工半双工数据顺序保证有序到达不保证顺序读写阻塞读阻塞、写阻塞仅读阻塞无写阻塞开销/延迟开销大、延迟高开销小、延迟低适用场景网页、文件传输、IM、数据库视频通话、游戏、物联网、广播三、TCP网络编程的核心步骤TCP是客户端-服务端模型的典型实现服务端需提前启动并监听端口客户端主动发起连接请求二者的编程步骤固定且分工明确相比UDPTCP增加了监听、连接、通信套接字分离等关键步骤。1. 核心概念监听套接字与通信套接字TCP服务端包含两类套接字二者功能分离是TCP编程的核心设计监听套接字listfd由socketbindlisten创建仅负责监听客户端的连接请求不参与实际的数据传输绑定固定的IP和端口生命周期贯穿整个服务端运行过程通信套接字connfd由accept函数创建每一个客户端连接对应一个独立的通信套接字负责与对应客户端的实际数据传输客户端断开连接后通信套接字被关闭。2. 完整编程流程【TCP服务端】 【TCP客户端】 1. 创建套接字socket→ SOCK_STREAM 2. 绑定IP和端口bind 3. 监听端口listen→ 进入监听状态 4. 阻塞等待连接accept→ 生成通信套接字connfd 5. 循环收发数据recv/send→ 基于connfd通信 6. 关闭通信套接字close→ 单个客户端通信结束 7. 关闭监听套接字close→ 服务端退出 ↓ 【客户端连接后】 1. 创建套接字socket→ SOCK_STREAM 2. 发起连接请求connect→ 向服务端listfd发起三次握手 3. 循环收发数据send/recv→ 基于自身socketfd通信 4. 关闭套接字close→ 客户端退出触发四次挥手核心要点服务端accept函数为阻塞函数若无客户端连接则一直阻塞有新连接则返回新的通信套接字服务端可通过多线程/多进程处理多个客户端连接一个connfd对应一个线程/进程客户端connect函数会触发三次握手握手失败则返回错误。四、TCP的连接机制三次握手与四次挥手TCP的三次握手建立连接和四次挥手断开连接是TCP协议的核心底层机制决定了连接的可靠性和资源的正常释放是网络编程的高频考点。1. 三次握手建立TCP连接三次握手的目的是确保客户端和服务端的发送、接收能力均正常并协商初始序列号建立可靠的通信链路涉及SYN同步报文和ACK确认报文两类核心报文流程如下第一次握手客户端 → 服务端发送SYN报文携带客户端初始序列号如seq1000并请求建立连接客户端进入SYN_SENT状态第二次握手服务端 → 客户端发送SYNACK报文一方面确认客户端的SYN报文ack1001序列号1另一方面携带服务端初始序列号如seq8000服务端进入SYN_RCVD状态第三次握手客户端 → 服务端发送ACK报文确认服务端的SYN报文ack8001序列号1客户端进入ESTABLISHED已建立连接状态服务端收到后也进入该状态此时TCP连接建立可开始数据传输。为什么需要三次握手避免失效的连接请求报文被服务端接收导致服务端建立无效连接浪费资源。若仅两次握手服务端发送SYNACK后若客户端未收到服务端会一直等待客户端的ACK造成资源占用三次握手通过客户端的最后一次ACK确保服务端知道客户端已收到连接确认连接建立有效。2. 四次挥手断开TCP连接TCP是全双工通信断开连接时双方需分别关闭各自的发送通道因此需要四次挥手涉及FIN结束报文和ACK确认报文两类核心报文流程如下第一次挥手主动关闭方 → 被动关闭方发送FIN报文表示主动关闭方不再发送数据主动关闭方进入FIN_WAIT_1状态第二次挥手被动关闭方 → 主动关闭方发送ACK报文确认FIN报文被动关闭方进入CLOSE_WAIT状态主动关闭方收到后进入FIN_WAIT_2状态此时主动关闭方的发送通道关闭被动关闭方可继续发送数据第三次挥手被动关闭方 → 主动关闭方发送FIN报文表示被动关闭方也不再发送数据被动关闭方进入LAST_ACK状态第四次挥手主动关闭方 → 被动关闭方发送ACK报文确认FIN报文主动关闭方进入TIME_WAIT状态等待2MSL确保被动关闭方收到ACK被动关闭方收到后进入CLOSED状态主动关闭方等待超时后也进入CLOSED状态TCP连接完全断开。为什么需要四次挥手因为TCP的全双工特性双方的发送通道是独立的。第一次挥手仅关闭主动关闭方的发送通道被动关闭方仍可发送数据因此需要第三次挥手由被动关闭方主动关闭自己的发送通道再通过第四次挥手确认完成全双工通道的全部关闭。五、TCP编程的核心问题黏包问题及解决方案TCP是流式套接字数据以连续的字节流传输无边界标识当发送方多次连续发送少量数据时TCP协议会为了提高传输效率将多个小数据块合并为一个大的数据块发送导致接收方一次接收到多个数据块无法正常拆分解析这就是黏包问题。1. 黏包问题产生的原因TCP的Nagle算法合并小数据块发送减少网络包数量提高传输效率接收方的接收缓冲区数据到达后先存入缓冲区接收方未及时读取导致多个数据块堆积在缓冲区一次读取时出现黏包发送方的发送缓冲区多个小数据块存入发送缓冲区被TCP一次性发送。2. 黏包问题的解决方案黏包问题的核心是为字节流添加“边界标识”让接收方能准确拆分不同的数据块实际开发中有三种主流解决方案可根据场景选择方案1设置固定的结束标志在每个数据块的末尾添加唯一的结束标志如\n、\0、###接收方读取数据时根据结束标志拆分数据块。优点实现简单适用于文本数据传输缺点若数据本身包含结束标志会导致解析错误需做转义处理。方案2发送固定大小的数据块发送方每次发送固定长度的数据接收方每次按固定长度读取若数据不足则补0接收方读取后剔除补位字符。优点解析简单无边界冲突问题缺点浪费带宽若数据长度差异大补位会造成不必要的传输开销。方案3自定义应用层协议推荐在数据块前添加数据头数据头中包含数据体的长度核心还可添加数据类型、版本号等信息接收方先读取数据头获取数据体长度再按长度精准读取数据体。优点灵活通用无边界冲突支持变长数据传输是工业级开发的主流方案缺点需自定义协议格式实现稍复杂。自定义协议示例// 定义数据头数据体的协议格式 typedef struct { int type; // 数据类型1-聊天消息2-文件传输 int data_len; // 数据体的实际长度 char reserve[8]; // 预留字段方便协议扩展 } TCP_HEADER; ​ typedef struct { TCP_HEADER header; // 数据头 char data[1024]; // 数据体存储实际数据 } TCP_MSG;发送方先计算数据体长度填充到data_len再发送整个TCP_MSG接收方先读取TCP_HEADER根据data_len读取对应长度的数据体完美解决黏包问题。六、TCP网络编程的核心函数Linux TCP网络编程基于Socket API核心函数与UDP有部分重合但新增了listen、accept、connect等关键函数同时数据收发使用recv/send替代UDP的recvfrom/sendto所有函数均为系统调用编译时无需额外链接库。1. 创建套接字socket与UDP一致仅需将套接字类型设为SOCK_STREAM流式套接字表示TCP协议int socket(int domain, int type, int protocol);参数domainAF_INET/PF_INETIPv4typeSOCK_STREAMTCP流式套接字protocol0自动匹配TCP协议返回值成功返回套接字文件描述符失败返回-1。示例int listfd socket(AF_INET, SOCK_STREAM, 0); if (listfd -1) { perror(socket error); exit(-1); }2. 绑定地址与端口bind与UDP完全一致将监听套接字与固定的IP和端口绑定服务端必须调用客户端可选int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);参数sockfd监听套接字描述符my_addrstruct sockaddr_inIPv4地址结构体需强制转换addrlen地址结构体大小sizeof(struct sockaddr_in)返回值成功返回0失败返回-1。3. 监听端口listen服务端专属函数将绑定后的套接字转换为监听套接字进入监听状态等待客户端连接int listen(int sockfd, int backlog);参数sockfd绑定后的套接字描述符backlog半连接队列的最大长度表示同时允许的待连接客户端数量一般设为5、10等返回值成功返回0失败返回-1。示例if (listen(listfd, 5) -1) { perror(listen error); close(listfd); exit(-1); }4. 接受连接accept服务端专属函数阻塞等待客户端的连接请求有新连接时返回通信套接字负责与该客户端的实际数据传输int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);参数sockfd监听套接字描述符listfdaddr输出参数存储客户端的IP和端口信息struct sockaddr_in不关心则设为NULLaddrlen输入输出参数传入地址结构体大小返回实际大小addr为NULL则设为NULL返回值成功返回通信套接字描述符connfd失败返回-1。示例struct sockaddr_in client_addr; socklen_t client_len sizeof(client_addr); int connfd accept(listfd, (struct sockaddr*)client_addr, client_len); if (connfd -1) { perror(accept error); continue; } printf(client [%s:%d] connected\n, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));5. 发起连接connect客户端专属函数向服务端的监听套接字发起连接请求触发三次握手建立TCP连接int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数sockfd客户端的套接字描述符addr服务端的地址结构体包含服务端IP和端口addrlen服务端地址结构体大小返回值成功返回0连接建立失败返回-1。示例struct sockaddr_in server_addr; memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; server_addr.sin_port htons(8888); server_addr.sin_addr.s_addr inet_addr(127.0.0.1); if (connect(sockfd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { perror(connect error); close(sockfd); exit(-1); }6. 接收数据recvTCP专属数据接收函数从套接字的接收缓冲区读取数据基于字节流无地址参数连接已建立无需指定对方地址ssize_t recv(int sockfd, void *buf, size_t len, int flags);参数sockfd服务端为通信套接字connfd客户端为自身套接字sockfdbuf存储接收数据的缓冲区len缓冲区大小避免数据溢出flags0阻塞接收默认返回值成功返回实际接收的字节数0表示对方已关闭套接字连接断开-1接收失败设置错误码。7. 发送数据sendTCP专属数据发送函数向套接字的发送缓冲区写入数据基于字节流无地址参数ssize_t send(int sockfd, const void *msg, size_t len, int flags);参数sockfd服务端为通信套接字connfd客户端为自身套接字sockfdmsg存储要发送数据的缓冲区len要发送的数据实际长度flags0阻塞发送默认返回值成功返回实际发送的字节数失败返回-1。8. 关闭套接字close与UDP一致关闭套接字描述符释放系统资源服务端需分别关闭通信套接字和监听套接字close(int sockfd);服务端close(connfd)关闭单个客户端的通信套接字、close(listfd)关闭监听套接字服务端退出客户端close(sockfd)关闭自身套接字触发四次挥手。七、Linux TCP网络编程完整实战示例下面实现一个单客户端的TCP回显服务服务端接收客户端发送的字符串原样返回给客户端包含服务端和客户端完整代码代码简洁易懂可直接在LinuxUbuntu/CentOS下编译运行同时解决了基础的黏包问题设置\n为结束标志。编译与运行说明编译分别编译服务端和客户端无需额外链接库gcc tcp_server.c -o tcp_server gcc tcp_client.c -o tcp_client运行先启动服务端再启动客户端服务端绑定本地8888端口客户端连接本地回环地址127.0.0.1功能客户端输入字符串服务端接收后原样返回客户端输入quit则退出同时断开TCP连接。1. TCP服务端代码tcp_server.c#include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h #define PORT 8888 #define BUF_SIZE 1024 int main() { // 1. 创建TCP监听套接字 int listfd socket(AF_INET, SOCK_STREAM, 0); if (listfd -1) { perror(socket error); exit(-1); } // 2. 设置地址复用避免端口占用可选 int opt 1; setsockopt(listfd, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt)); // 3. 绑定IP和端口 struct sockaddr_in server_addr; memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; server_addr.sin_port htons(PORT); server_addr.sin_addr.s_addr inet_addr(0.0.0.0); // 绑定所有本地IP if (bind(listfd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { perror(bind error); close(listfd); exit(-1); } // 4. 监听端口 if (listen(listfd, 5) -1) { perror(listen error); close(listfd); exit(-1); } printf(TCP server start, listen port %d...\n, PORT); // 5. 阻塞等待客户端连接 struct sockaddr_in client_addr; socklen_t client_len sizeof(client_addr); int connfd accept(listfd, (struct sockaddr*)client_addr, client_len); if (connfd -1) { perror(accept error); close(listfd); exit(-1); } printf(client [%s:%d] connected successfully\n, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // 6. 循环收发数据回显服务 char buf[BUF_SIZE] {0}; while (1) { // 接收客户端数据 ssize_t recv_len recv(connfd, buf, BUF_SIZE-1, 0); if (recv_len -1) { perror(recv error); break; } else if (recv_len 0) { printf(client [%s:%d] disconnected\n, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } buf[recv_len] \0; // 字符串结束符 // 客户端输入quit则退出 if (strcmp(buf, quit) 0) { printf(client [%s:%d] quit\n, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } // 打印接收的数据并回显给客户端 printf(recv from client: %s\n, buf); send(connfd, buf, strlen(buf), 0); // 清空缓冲区 memset(buf, 0, sizeof(buf)); } // 7. 关闭套接字 close(connfd); // 关闭通信套接字 close(listfd); // 关闭监听套接字 return 0; }2. TCP客户端代码tcp_client.c#include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h #define SERVER_IP 127.0.0.1 #define SERVER_PORT 8888 #define BUF_SIZE 1024 int main() { // 1. 创建TCP套接字 int sockfd socket(AF_INET, SOCK_STREAM, 0); if (sockfd -1) { perror(socket error); exit(-1); } // 2. 配置服务端地址并发起连接 struct sockaddr_in server_addr; memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; server_addr.sin_port htons(SERVER_PORT); server_addr.sin_addr.s_addr inet_addr(SERVER_IP); if (connect(sockfd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { perror(connect error); close(sockfd); exit(-1); } printf(connect to TCP server [%s:%d] successfully\n, SERVER_IP, SERVER_PORT); printf(input quit to exit\n); // 3. 循环收发数据 char send_buf[BUF_SIZE] {0}; char recv_buf[BUF_SIZE] {0}; while (1) { // 输入要发送的字符串 printf(please input message: ); fgets(send_buf, BUF_SIZE-1, stdin); // 去除fgets的换行符解决黏包以\n为结束标志 send_buf[strcspn(send_buf, \n)] \0; // 发送数据到服务端 send(sockfd, send_buf, strlen(send_buf), 0); // 输入quit则退出 if (strcmp(send_buf, quit) 0) { break; } // 接收服务端的回显数据 ssize_t recv_len recv(sockfd, recv_buf, BUF_SIZE-1, 0); if (recv_len -1) { perror(recv error); break; } else if (recv_len 0) { printf(server disconnected\n); break; } recv_buf[recv_len] \0; printf(recv from server: %s\n, recv_buf); // 清空缓冲区 memset(send_buf, 0, sizeof(send_buf)); memset(recv_buf, 0, sizeof(recv_buf)); } // 4. 关闭套接字 close(sockfd); printf(client exit\n); return 0; }3. 运行结果# 服务端终端 $ ./tcp_server TCP server start, listen port 8888... client [127.0.0.1:53210] connected successfully recv from client: Hello TCP Server! recv from client: Linux Network Programming client [127.0.0.1:53210] quit # 客户端终端 $ ./tcp_client connect to TCP server [127.0.0.1:8888] successfully input quit to exit please input message: Hello TCP Server! recv from server: Hello TCP Server! please input message: Linux Network Programming recv from server: Linux Network Programming please input message: quit client exit4. 扩展多客户端处理上述示例为单客户端处理实际服务端需要支持多个客户端同时连接可通过多线程或多进程实现多线程每一个客户端连接connfd创建一个独立的线程线程中处理该客户端的收发数据多进程通过fork()创建子进程子进程处理该客户端的收发数据父进程继续等待新连接。多线程核心示例// 线程处理函数参数为通信套接字connfd void* client_handler(void* arg) { int connfd *(int*)arg; free(arg); // 释放动态分配的内存 // 此处编写收发数据的逻辑与单客户端一致 close(connfd); pthread_exit(NULL); } ​ // 在accept后创建线程 int *p malloc(sizeof(int)); *p connfd; pthread_t tid; pthread_create(tid, NULL, client_handler, p); pthread_detach(tid); // 设置线程分离属性自动回收资源八、TCP编程的核心注意事项端口复用服务端重启时若端口处于TIME_WAIT状态会导致bind失败可通过setsockopt设置SO_REUSEADDR选项实现地址复用字节序转换IP地址和端口号必须转换为网络字节序大端使用htonl、htons、inet_addr等函数避免地址解析错误recv返回0的处理recv返回0表示对方已关闭套接字需及时关闭本地的通信套接字避免资源泄漏黏包问题实际开发中必须处理黏包问题推荐使用自定义应用层协议的方式兼容变长数据传输多客户端处理单线程服务端仅支持一个客户端需通过多线程/多进程/IO多路复用select/poll/epoll实现多客户端并发处理套接字关闭服务端需区分通信套接字和监听套接字客户端断开后仅关闭connfdlistfd需在服务端退出时关闭异常处理对所有系统调用的返回值做异常处理如socket、bind、listen、accept、recv、send避免程序崩溃。九、总结本文详细讲解了TCP协议的核心特性、网络编程步骤、底层连接机制及黏包问题解决方案并通过完整的代码示例实现了TCP回显服务核心知识点可总结为TCP是面向连接、可靠、全双工的流式传输协议通过三次握手建立连接、四次挥手断开连接实现数据的有序、可靠传输TCP服务端包含监听套接字listfd和通信套接字connfd二者功能分离一个客户端连接对应一个独立的connfdTCP编程的核心步骤为服务端socket→bind→listen→accept→recv/send→close客户端socket→connect→send/recv→close黏包问题是TCP流式套接字的固有问题核心解决方案为添加边界标识推荐使用自定义应用层协议数据头数据体TCP适用于对数据可靠性、顺序性要求高的场景如网页、文件传输、IM、数据库而UDP适用于实时性要求高的场景单线程TCP服务端仅支持一个客户端实际开发中需通过多线程/多进程/IO多路复用实现多客户端并发处理。至此Linux网络编程的两大核心协议UDP/TCP已全部讲解完毕结合之前的多线程、进程间通信知识你已掌握Linux系统编程的核心基础。后续可进一步学习IO多路复用select/poll/epoll、高并发服务器开发、HTTP协议与Web开发等进阶内容实现更复杂的网络应用。

相关新闻

Qwen3模型服务化:Dify平台集成与工作流搭建

Qwen3模型服务化:Dify平台集成与工作流搭建

Qwen3模型服务化:Dify平台集成与工作流搭建 你是不是已经用星图平台部署好了Qwen3模型,感觉它能力挺强,但总觉得还差点意思?比如,每次调用都得写代码,想做个带界面的应用给同事用,或者想把模型…

2026/7/3 10:39:47 阅读更多 →
阿里MGeo模型实战:10分钟学会地址匹配,告别人工比对

阿里MGeo模型实战:10分钟学会地址匹配,告别人工比对

阿里MGeo模型实战:10分钟学会地址匹配,告别人工比对 你是不是也遇到过这样的烦恼?手里有一堆客户地址数据,有的写“北京市朝阳区建国门外大街1号”,有的写“北京朝阳建国门附近”,还有的写“建国门外大街1…

2026/7/4 8:56:09 阅读更多 →
Jimeng LoRA效果实测:jimeng系列对复杂Prompt长句结构的理解能力

Jimeng LoRA效果实测:jimeng系列对复杂Prompt长句结构的理解能力

Jimeng LoRA效果实测:jimeng系列对复杂Prompt长句结构的理解能力 1. 项目概述 今天我们来实测一款特别的AI绘画工具——Jimeng LoRA测试系统。这个系统基于Z-Image-Turbo文生图底座,专门用来测试Jimeng(即梦)系列LoRA模型的不同…

2026/5/17 9:18:29 阅读更多 →

最新新闻

Elm-platform安装教程:Windows、macOS、Linux三大平台详细步骤

Elm-platform安装教程:Windows、macOS、Linux三大平台详细步骤

Elm-platform安装教程:Windows、macOS、Linux三大平台详细步骤 【免费下载链接】elm-platform Bundle of all core development tools for Elm 项目地址: https://gitcode.com/gh_mirrors/el/elm-platform 想要开始 Elm 编程之旅吗?Elm-platform …

2026/7/4 8:55:25 阅读更多 →
量子增强侧信道与迭代攻击:后量子密码(如McEliece)的混合威胁与防御实践

量子增强侧信道与迭代攻击:后量子密码(如McEliece)的混合威胁与防御实践

1. 项目概述:当量子计算遇上经典密码 最近在密码学圈子里,一个听起来有点“缝合怪”但又极具前瞻性的概念被反复提及——“量子相关密钥攻击迭代EM密码”。乍一看,这标题融合了“量子”、“密钥攻击”、“迭代”和“EM密码”几个硬核词汇&…

2026/7/4 8:55:25 阅读更多 →
Linux/WSL终端美化指南:gh_mirrors/do/dotfiles-archive的zsh与Hyper配置技巧

Linux/WSL终端美化指南:gh_mirrors/do/dotfiles-archive的zsh与Hyper配置技巧

Linux/WSL终端美化指南:gh_mirrors/do/dotfiles-archive的zsh与Hyper配置技巧 【免费下载链接】dotfiles-archive Dotfiles for all :D 项目地址: https://gitcode.com/gh_mirrors/do/dotfiles-archive gh_mirrors/do/dotfiles-archive项目提供了一套完整的终…

2026/7/4 8:55:25 阅读更多 →
高速PCB阻抗设计3大误区:线宽、铜厚与阻焊对±10%公差的实际影响

高速PCB阻抗设计3大误区:线宽、铜厚与阻焊对±10%公差的实际影响

高速PCB阻抗设计实战:破解线宽、铜厚与阻焊的10%公差迷思1. 阻抗设计的基础认知误区在高速PCB设计中,阻抗控制绝非简单的理论计算问题。许多工程师习惯将IPC标准中的公式直接套用,却忽略了实际制造环节中至少12个关键变量对最终阻抗值的影响。…

2026/7/4 8:55:25 阅读更多 →
PAT 乙级题目讲解:1006《换个格式输出整数》

PAT 乙级题目讲解:1006《换个格式输出整数》

✅ PAT 乙级题目讲解:1006《换个格式输出整数》摘要: 本文讲解 PAT 乙级真题 1006《换个格式输出整数》。题目要求将三位数按百位、十位、个位拆分,并分别以字母 B、S 和自然数序列输出。文章通过样例分析、分步拆解代码、完整实现、常见错误…

2026/7/4 8:51:24 阅读更多 →
PAT 乙级题目讲解:1016《部分A+B》

PAT 乙级题目讲解:1016《部分A+B》

✅ PAT 乙级题目讲解:1016《部分AB》🧩 题目简题目摘要:本题目要求从两个正整数中分别提取指定数字并拼接成新整数,计算其和。核心考察字符串提取与数字构造的模拟实现,时间复杂度 O(n)\mathcal{O}(n)O(n),…

2026/7/4 8:49:23 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻