正向代理与反向代理
1. 代理技术基础概念1.1 代理服务器定义代理服务器(Proxy Server)是位于客户端(Client)和目标服务器(Target Server)之间的网络中间节点,负责接收客户端的网络请求、转发至目标服务器,并将目标服务器的响应回传至客户端。其核心价值在于隐藏真实通信端点、控制网络流量、优化访问性能及增强网络安全。 1.2 代理技术的核心作用 通信中转:实现客户端与目标服务器的间接通信,解决直接连接受限问题 流量控制:基于规则过滤、转发或拦截网络请求(如企业内网访问策略) 性能优化:通过缓存常用资源、压缩数据减少网络传输量 安全防护:隐藏真实 IP 地址,隔离内外网,抵御部分网络攻击 2. 正向代理(Forward Proxy)技术原理2.1 正向代理定义正向代理是代理服务器为客户端提供服务的代理模式,客户端明确知道目标服务器地址,通过正向代理间接访问目标服务器。此时,代理服务器代表客户端与目标服务器通信,目标服务器无法直接获取客户端的真实 IP 地址。 2.2 正向代理工作流程 客户端配置正向代理服务器的地址及端口,明确目标服务器地址 客户端向正向代理发送请...
HTTP客户端实现 - 百度首页探寻
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146#include <sys/socket.h>#include <sys/types.h>#include <netdb.h>#include <cstring>#include <unistd.h>#include <cerrno>#include <c...
数据库事务隔离机制全面解析:并发问题与解决方案
一、事务与并发控制基础1.1 事务ACID特性在分布式系统中,事务需要满足以下核心特性: 原子性:事务操作不可分割,全部完成或全部失败 一致性:事务执行前后数据库状态保持一致 隔离性:事务之间相互隔离,避免并发执行的干扰 持久性:事务提交后永久生效,即使系统崩溃也不会丢失 对于InnoDB存储引擎,ACID特性通过日志系统(Redo Log)和多版本并发控制(MVCC)实现,MySQL 8.0版本后已完全支持事务性存储引擎。 1.2 并发问题分类体系四个经典的并发问题及其表现形式: 问题类型 定义说明 典型场景 脏写 事务A写入数据后未提交,事务B又覆盖该数据,导致A的写入被B无效 两个事务对同一行数据进行并发修改,典型例子为数据库主从复制中的write-ahead log问题 脏读 事务A写入未提交数据,事务B读取该数据导致读取到无效数据 高并发读取场景,如统计报表生成时读取未提交的业务数据 不可重复读 事务A读取数据后,事务B修改该数据并提交,导致A再次读取时结果不同 需要保证数据一致性的金融交易场景 幻读 事务A读取数据集后,事务B插入新数据...
上传下载系列的整理修改改改 - 服务端 - 4
CD\LS命令12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152#include "Server.h"// CD命令实现int CmdCd(char *path, const int depth, FileBuf_t *msg, Node_t *p){ DIR *dir =opendir(path); if(dir == NULL){ sprintf(msg->buf, "(error: %s)", strerror(errno)); return -1; }else{ p->depth = depth; char *help; char *pathblock = strtok_r(path, " /", &help); f...
上传下载系列的整理修改改改 - 服务端 - 3
服务端信息处理123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111#include "Server.h"// 接收并处理命令int RecvCommand(Node_t *p){ int netfd = p->netfd; //接收指令 SignalSend_t *cmd = (SignalSend_t *)calloc(1, sizeof(SignalSend_t)); if (cmd == NULL){ printf("Error calloc\n"); syslog(...
上传下载系列的整理修改改改 - 服务端 - 2
服务端登录验证123456789101112131415161718192021222324252627282930313233343536373839#include "Server.h"//#include <shadow.h>//#include <crypt.h>//#include <syslog.h>int IsLoading(int netfd){ if(send(netfd, "请输入用户名和密码", sizeof("请输入用户名和密码"), 0) <= 0){ printf("error recv loadmsg\n"); return -1; } char load[2][PATHLEN]; char *username = load[0]; if(recv(netfd, load, 2 * PATHLEN, 0) <= 0){ ...
上传下载系列的整理修改改改 - 服务端 - 1
服务端头文件123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384#ifndef SERVER_H#define SERVER_H#include "my_header.h"#include <arpa/inet.h>#include <fcntl.h>#include <dirent.h>#include <sys/mman.h>#include <unistd.h>#include <pthread.h>#include <netinet/in.h>#include <sys/epoll.h>#include <sys/types.h>#include <sys/socket.h>...
上传下载系列的整理修改改改 - 2
收发文件循环接收12345678910#include "Client.h"int recvn(int sockfd, void *buf, int size){ int total = 0; char *p = (char *)buf; while(total < size){ ssize_t sret = recv(sockfd, p+total, size-total, 0); total += sret; } return total;} 收文件根据对方发送的文件名,在当下实现文件的接收 123456789101112131415161718192021222324252627282930313233343536int RecvFile(int sockfd){ FileBuf train; char filename[128] = {0}; recv(sockfd, &train.size, ...
上传下载系列的整理修改改改
导言最近学习完成了数据库和多人聊天室,想基于这些东西,设计一个老掉牙的网盘项目(才不是收到齐哥刺激)。目前是只有空闲时间能做,大概还是跟之前更新一样,大概一周一更慢慢写。 头文件1234567891011121314151617181920212223242526272829303132333435/* Usage: 实现收发功能,收消息没有限制,发消息需要信号,Switch判断发送,结构体发送指令,接收消息,接收文件*/#ifndef CLIENT_H#define CLIENT_H#include "my_header.h"#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <pthread.h>#include <netinet/in.h>#include <sys/epoll.h>#include <sys/types.h>#include <sys/socket.h>#in...
TCP 文件传输系统:事件驱动与线程池协同架构下的代码解构与设计实践
一、引言在网络通信领域,TCP 协议凭借其强大的可靠性与稳定性,成为文件传输系统的首选。本教程聚焦于基于 TCP 的多线程文件传输系统,深入剖析事件驱动与线程池协同工作的架构设计。支持双向消息交互与文件传输,由九个核心文件构成,全面覆盖网络连接建立、事件监听、线程管理以及数据传输等关键环节。 二、代码结构分析1. 文件概览 文件名 主要功能 核心函数列表 head.h 全局结构体定义与函数声明 结构体:Train(封装消息与文件传输数据)、Queue_t(定义客户端连接队列结构)、Res_t(线程池资源相关结构体);函数声明:Ready(服务器套接字初始化)、EpollAdd(将文件描述符添加到 epoll 监听列表)等 client.c 客户端主逻辑实现 main函数包含事件驱动循环,集成消息处理、连接状态管理及用户输入响应等模块,负责客户端的连接管理与数据通信。 Server.c 服务器核心逻辑 main函数基于 epoll 事件驱动机制,整合信号处理模块,实现客户端连接接收、消息转发及线程池任务调度,是服务器的核心控制中枢。 Ready.c 服务器套接...
进程间通信:pipe 与 socketpair 对比
一、pipe 机制详解1.1 管道的基本概念管道 (pipe) 是 Unix 系统中最古老的 IPC 机制之一,它通过一对文件描述符实现进程间的单向通信: 一个文件描述符用于读取数据 (fd[0]) 另一个文件描述符用于写入数据 (fd[1]) 数据在管道中以先进先出 (FIFO) 的方式传输 管道本质上是内核维护的一个缓冲区,其大小因系统而异 (通常为 64KB),当缓冲区满时,写入操作会阻塞;当缓冲区空时,读取操作会阻塞。 1.2 pipe () 系统调用12#include <unistd.h>int pipe(int pipefd[2]); 成功时返回 0,失败时返回 -1 并设置 errno pipefd[0]:读取端文件描述符 pipefd[1]:写入端文件描述符 1.3 父子进程通信实现使用 pipe 进行父子进程通信的典型流程: 创建管道 调用 fork() 创建子进程 关闭不需要的文件描述符 进行数据读写操作 关闭所有文件描述符 1234567891011121314151617181920212223242526...
多进程文件传输服务器与客户端实现
引言本文将详细解析一个基于多进程模型的文件传输系统,该系统包含服务器端和客户端两部分。服务器端采用进程池设计模式,通过预先创建多个工作进程来处理客户端的文件请求,提高系统的并发处理能力。客户端则负责接收服务器传输的文件并显示传输进度。 一、系统整体架构该系统主要由以下几个部分组成: 服务器端: 主进程:负责监听客户端连接、管理工作进程池 工作进程:实际处理文件传输任务 进程间通信:通过 UNIX 域套接字传递文件描述符 客户端: 连接服务器 接收文件数据 显示传输进度 二、核心数据结构1. Train 结构体1234typedef struct Train{ int size; char data[1024];}Train; 功能描述:用于文件数据的传输封装 结构说明: size:表示data数组中有效数据的长度 data:存储实际的文件数据,最大为 1024 字节 2. WorkerData 结构体12345typedef struct WorkerData{ pid_t pid; int st...
网络编程中的系统调用与信号处理机制
一、sendfile 系统调用解析1.1 技术要点sendfile 作为基于 Unix/Linux 操作系统的高效文件传输系统调用,其函数原型定义为: 1ssize\_t sendfile (int out\_fd, int in\_fd, off\_t \*offset, size\_t count); 各参数语义阐释如下: out_fd:数据输出目标文件描述符,常用于指向网络编程中的套接字描述符。 in_fd:数据输入源文件描述符,需支持内存映射(mmap)操作。 offset:文件读取偏移指针,设为 NULL 时启用系统默认偏移并自动更新。 count:指定待传输数据字节长度。 sendfile 的核心优势在于零拷贝技术,数据传输在内核空间完成,避免用户与内核空间的数据拷贝开销。传统 I/O 需四次上下文切换与四次数据拷贝,而 sendfile 仅需两次上下文切换和两次数据拷贝,大幅提升传输效率。 1.2 应用场景sendfile 系统调用适用于静态资源服务器文件传输、视频流媒体分发、大规模文件传输及高性能计算等对传输性能要求高的场景。 1...
多进程并发服务器的选择与放弃
一、早期搭建原因与后续放弃原因1.1 早期搭建原因 硬件适配与稳定性保障:早期服务器开发受限于单核 CPU 与有限内存,进程池架构通过预创建固定进程,规避频繁进程操作开销,利用进程资源隔离特性,防止单业务异常拖垮整个系统。 技术成熟与高效处理:多进程编程结合epoll事件驱动模型已趋成熟,凭借epoll对活跃事件的精准处理,服务器在高并发场景下实现资源高效利用。 性能优化策略:无锁化调度与动态负载均衡,有效化解多进程资源竞争,均衡任务分配,提升服务整体处理性能。 1.2 后续放弃原因 资源管理局限:业务扩张与用户增长时,固定进程池难以适配动态负载。高并发下请求排队导致响应延迟,且进程独占内存,数量过多易造成资源浪费,灵活性不足。 切换开销较大:进程池虽减少创建销毁频率,但上下文切换仍有开销。多核时代,线程作为轻量级单元,切换开销远低于进程,更适合高并发短周期任务,削弱多进程架构优势。 新技术的冲击:Node.js、Golang 等语言框架自带高效异步 I/O 与协程模型,开发效率和性能俱佳;Nginx 事件驱动架构成行业标杆,传统多进程服务器逐渐被替代。 二、主函数...
Linux 进程间文件描述符传输技术详解
导言在 Linux 系统编程中,进程间通信(IPC)是核心课题。传统 IPC 机制如管道、消息队列和共享内存各有优势,但在高性能服务器、分布式系统等场景下存在局限,亟需更灵活的通信方式。 一、文件描述符传输的原理文件描述符作为进程私有资源标识,无法直接跨进程传递。因为不同进程的文件描述符表相互独立,同一数值在不同进程中可能指向不同资源。例如父进程中文件描述符 3 指向网络套接字,直接传递数值 3 给子进程,子进程的 3 可能指向标准输入。因此,需借助 Unix 域套接字等专门 IPC 机制传递。 在 Linux 中,文件描述符是进程访问 I/O 资源的抽象句柄,默认具有进程私有性。而在高并发服务器、分布式文件系统等场景下,传递文件描述符能提升资源复用与协作效率。其实现核心是利用 Linux 辅助数据机制,常通过 socketpair 创建 UNIX 域套接字,配合 sendmsg 和 recvmsg 系统调用完成。 二、代码实现分析伪代码部分扩展 为了更清晰地展示文件描述符传输的核心逻辑,以下通过伪代码对关键函数SendFd和RecvFd进行流程拆解,并补充更直观的主程...
多进程编程:早期服务器实现逻辑
一、核心逻辑的伪代码解释1.1 主程序逻辑1234567891011121314151617181920212223主程序开始: 打开文件"1.txt"用于读写 如果文件打开失败: 输出错误信息并退出程序 向文件中写入"nonono"字符串 如果写入失败: 关闭文件 输出错误信息并退出程序 强制将缓冲区数据写入磁盘 分配能存储3个workerData_t结构体的内存空间 如果内存分配失败: 关闭文件 输出错误信息并退出程序 调用MakeWorker函数创建3个工作进程 如果创建失败: 释放已分配的内存 关闭文件 输出错误信息并退出程序 对于每个工作进程: 等待该进程执行结束 释放内存空间 关闭文件 正常退出程序 主程序首先尝试打开文件并写入内容,确保数据持久化。接着分配内存存储工作进程信息,调用MakeWorker函数创建子进程,最后等待...
聊天改了又改版:基于 epoll 的简易多人聊天服务器与客户端实现
导言今天是聊天室,改了又改版本,目前更改部分包括:放弃了好用但是实现复杂的链表,采用数组来实现信息存储;时间结构采用ctime函数;用epoll代替select;生成历史记录文件等。 本代码实现的简易多人聊天系统主要包含两个部分: 服务器端:支持多客户端连接,具备消息广播、私聊以及超时检测功能。 客户端:负责与服务器建立连接,实现消息的发送与接收。 系统采用 TCP 协议进行通信,并运用 epoll 实现 I/O 多路复用。相较于传统的 select/poll 模型,在高并发场景下,epoll 展现出更出色的性能。 一、核心技术点解析1.1 epoll I/O 多路复用epoll 是 Linux 系统下高效的 I/O 事件通知机制,本项目主要使用了以下函数: epoll_create():用于创建 epoll 实例。 epoll_ctl():可添加、删除或修改被监控的文件描述符。 epoll_wait():用于等待事件发生。 服务器和客户端均通过 epoll 同时监控 socket 和标准输入,实现了非阻塞的 I/...
select 与 epoll 的核心区别整理
一、底层数据结构与核心代码对比 特性 select epoll 数据结构 固定大小位图(bitmap)。这种结构通过位标记文件描述符是否就绪,存在明显局限性:一是 FD_SETSIZE 限制了可监控的文件描述符数量上限,二是每次轮询都需遍历整个位图,效率随连接数增加而降低。 采用红黑树 + 就绪链表的组合。红黑树用于高效管理所有注册的文件描述符,插入、删除操作时间复杂度为 O (log n);就绪链表则存放当前就绪的事件,epoll_wait 调用时仅需处理就绪链表,避免无意义的遍历,大幅提升高并发场景下的查询效率。 核心代码示例 c #include fd_set readfds; FD_ZERO(&readfds); FD_SET(fd, &readfds); select(max_fd + 1, &readfds, NULL, NULL, NULL); c #include int epollfd = epoll_create(1024); struct epoll_event event; event.data.fd = fd;...
基于多人聊天室系统的实现,详细学习 epoll 函数基础
导言:在 Linux 高并发网络编程中,epoll 作为事件驱动的 I/O 多路复用方案,是构建高性能服务器的核心技术。本文从原理、使用到实践,全面解析 epoll 的技术要点。 一、epoll 的核心优势 事件驱动:相较于select/poll的遍历式轮询,epoll 采用事件驱动架构,由内核主动推送就绪 I/O 事件。高并发场景下,仅少量连接就绪时,epoll 可精准定位活跃连接,避免全量扫描带来的 CPU 损耗,大幅提升资源利用率。 海量连接:select受限于固定长度数组(默认上限 1024),难以应对高并发。epoll 采用动态数据结构,连接上限仅受系统文件描述符表限制(可通过ulimit -n调整),可支撑数万至数十万级并发连接。 高效结构:epoll 以红黑树管理监控列表,文件描述符操作时间复杂度为O(log n);就绪事件链表支持O(1)级快速检索。这种设计确保海量连接下的高效响应与处理。 二、核心函数解析123456789101112131415161718192021#include <sys/epoll.h>int e...
Linux:多人聊天室系统实现 - 改版:从功能设计到代码解析
导言在网络编程领域,聊天室系统是一个经典的实践案例,它涵盖了套接字通信、并发处理、数据结构应用等多个核心知识点。本文将从零开始,一步步讲解如何使用 C 语言实现一个支持多人聊天、超时管理和私聊功能的完整聊天室系统,包括服务器端和客户端的实现细节。同时,为了让代码更具可读性和可维护性,会对关键代码段添加详细注释,帮助读者更好地理解每一步的逻辑。 一、系统整体设计与功能规划1.1 核心功能定位本聊天室系统旨在实现一个轻量化的多人即时通信工具,通过逐步迭代的方式完成以下功能: 基础双人通信:实现两个客户端之间通过服务器转发消息,为后续多人通信奠定基础。在开发初期先聚焦双人通信,能简化调试流程,快速验证消息转发逻辑。 多人聊天功能:支持多个客户端同时连接并进行群聊,满足多人实时交流需求。该功能适用于在线讨论、小组协作等场景,是聊天室的核心使用场景。 超时管理机制:对长时间不活跃的客户端进行自动清理,释放系统资源,保持服务器高效运行。当服务器连接数较多时,此机制能有效避免资源浪费,提升整体性能。 私聊功能:允许客户端之间建立一对一的私密对话,保护用户隐私。用户在需要分享敏感信息或进...
基于多人聊天室系统的实现,学习 setsockopt 函数:从代码到实践
导言在网络通信领域的研究与实践中,套接字选项的配置是网络编程的核心技术环节之一。setsockopt函数作为配置套接字选项的核心接口,其使用机制与应用场景对网络程序性能优化和稳定性保障具有重要意义。本文将结合具体的代码实现,系统探讨setsockopt函数的参数结构、应用方法及典型套接字选项的配置策略。 一、setsockopt 函数的理论基础setsockopt函数定义于sys/socket.h头文件,其函数原型为: 12#include <sys/socket.h>int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); 各参数的语义解析如下: sockfd:表示目标套接字的文件描述符,作为操作对象的唯一标识 level:指定选项所属的协议层次,其中SOL_SOCKET用于通用套接字选项配置,IPPROTO_TCP专用于 TCP 协议相关设置 optname:具体要配置的选项名称,决定配置行为的类型 optval:指向选项值...
基于多人聊天室系统的实现,详细学习select 函数基础
一、select 函数基础与定时机制在网络编程中,select函数是一种常用的 I/O 多路复用技术,它允许程序同时监控多个文件描述符,等待其中任何一个变为 "就绪" 状态(可读、可写或异常)。select函数的原型如下: 1234#include <sys/select.h>int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 其中,timeout参数是一个指向struct timeval的指针,用于设置select函数的最大等待时间: 1234struct timeval { long tv_sec; /* 秒 */ long tv_usec; /* 微秒 */}; 这个参数实现了select函数的定时机制,具体分为三种情况: timeout == NULL:无限等待,直到有文件描述符就绪 timeout->...
Linux:基于 select 多路复用的 C 语言多人聊天室实现
一、项目概述与核心功能本聊天室服务器基于 TCP 协议,通过select多路复用技术,实现单线程高效处理多个连接。其核心功能包括: 稳定连接:利用 TCP 协议确保数据传输的可靠性; 高效处理:借助select系统调用,提升服务器并发处理能力; 多样交互:支持群聊和私聊两种模式; 智能管理:设置 30 秒无活动超时机制,自动清理闲置连接; 日志追踪:记录服务器关键事件与客户端活动,便于监控与调试; 控制台广播:管理员可通过控制台向所有在线客户端发送消息。 二、核心技术点 select多路复用:允许单线程同时处理多个文件描述符(如监听套接字、客户端连接和标准输入),降低多线程编程的复杂度与资源消耗。 链表数据结构:采用双向链表动态管理客户端连接信息,便于节点的添加、删除与遍历操作。 TCP socket 编程:完整实现套接字创建、地址绑定、端口监听和连接接受等网络通信核心操作。 时间处理机制:通过高精度时间戳生成函数,实现超时检测与日志记录功能。 三、代码模块解析3.1 时间戳工具函数123456789101112131415// 获取时间戳字符串char* get_time...
基于 TCP 协议的双向通信程序实现与解析
一、整体工作流程本代码实现的内网聊天系统采用经典的客户端 - 服务器(C/S)架构模型。系统运行过程中,服务器端与客户端分别遵循以下工作流程: 服务器端的初始化阶段,依次执行 socket 创建、端口绑定及监听状态设置等操作。随后进入循环监听模式,默认设置 5 秒超时机制等待客户端连接请求。当客户端成功连接后,服务器与客户端进入双向通信状态,双方可通过标准输入输出进行消息交互。客户端断开连接后,服务器将关闭当前连接通道,重新进入待连接状态,以处理后续客户端请求。 客户端在初始化时,通过创建 socket 实例并连接至服务器指定端口建立通信链路。连接成功后,客户端启动消息交互循环,实现用户输入消息的发送与服务器响应消息的接收功能。当满足预设退出条件时,客户端将主动断开与服务器的连接,并安全退出程序。 系统基于 TCP 协议通过 socket 接口建立连接,运用 select 函数实现 I/O 多路复用机制,同时监听标准输入及网络数据接收事件,确保通信过程的高效性与可靠性。各功能模块协同配合,共同完成消息收发、时间戳记录及会话管理等核心功能。 二、关键函数作用2....
基于 UDP 协议的双向通信程序实现与解析
引言用户数据报协议(UDP)作为 TCP/IP 协议簇中的核心协议之一,以其无连接、低开销的特性,在实时通信、物联网数据传输等场景中发挥着重要作用。与 TCP 协议的面向连接、可靠传输不同,UDP 协议提供的是一种尽最大努力交付的服务,不保证数据的有序到达和不丢失,这使得其在对实时性要求较高而对可靠性要求相对较低的场景中具有显著优势。 本文将对一套基于 UDP 协议实现的双向通信程序进行深入解析,包括客户端与服务器端的代码结构、关键函数调用、程序运行逻辑以及实际通信案例分析,旨在揭示 UDP 协议在实际编程中的应用方式与技术细节。 一、程序整体架构与设计思路本次分析的程序采用 C 语言编写,基于 Linux 系统的套接字(socket)API 实现,包含客户端和服务器端两个独立的程序模块。两套程序均采用了 I/O 多路复用技术(select 函数)实现标准输入和网络套接字的同时监听,从而实现双向通信功能。 程序的核心设计思路在于: 利用 UDP 协议的无连接特性,无需建立连接即可直接发送数据 通过 select 函数实现 I/O 多路复用,同时监...

