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

成都网站建设外包公司排名wordpress 缺少临时文件夹

成都网站建设外包公司排名,wordpress 缺少临时文件夹,wordpress文件上传失败,北京微网站制作价格TCP套接字编程详解:从API到实战细节 一、TCP通信整体流程 TCP是面向连接的可靠传输协议,其通信流程需严格遵循“服务器绑定监听→客户端连接→数据交互→断开连接”的步骤。以下是服务器和客户端的核心流程对比:角色核心流程(常用…

TCP套接字编程详解:从API到实战细节

一、TCP通信整体流程

TCP是面向连接的可靠传输协议,其通信流程需严格遵循“服务器绑定监听→客户端连接→数据交互→断开连接”的步骤。以下是服务器和客户端的核心流程对比:

角色核心流程(常用API)
服务器创建套接字 socket() → 绑定地址端口 bind() → 监听连接 listen() → 接受连接 accept() → 数据交互 read()/write() → 关闭连接 close()
客户端创建套接字 socket() → 连接服务器 connect() → 数据交互 read()/write() → 关闭连接 close()

二、核心API详解(Linux环境)

1. 创建套接字:socket()

功能:创建一个网络套接字(文件描述符),用于后续网络通信。

#include <sys/socket.h>  
int socket(int domain, int type, int protocol);  
参数说明:
  • domain(协议族):指定网络协议类型
    • AF_INET:IPv4协议(最常用);AF_INET6:IPv6协议;AF_UNIX:本地套接字(进程间通信)。
  • type(套接字类型):指定传输方式
    • SOCK_STREAM:流式套接字(对应TCP协议,可靠连接);
    • SOCK_DGRAM:数据报套接字(对应UDP协议,无连接)。
  • protocol(协议):一般填 0,表示使用 type 对应的默认协议(TCP用 IPPROTO_TCP,UDP用 IPPROTO_UDP,但通常省略)。
示例:创建TCP套接字
int server_fd = socket(AF_INET, SOCK_STREAM, 0);  
if (server_fd == -1) {  perror("socket创建失败");  exit(1);  
}  

2. 绑定地址和端口:bind()

功能:将套接字与本地IP地址和端口号绑定(服务器必须绑定,客户端通常由系统自动分配端口)。

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);  
参数说明:
  • sockfdsocket() 返回的套接字描述符。
  • addr:指向地址结构体的指针(需填充IP、端口等信息)。
    • IPv4使用 struct sockaddr_in(需强制转换为 sockaddr*):
    struct sockaddr_in serv_addr;  
    serv_addr.sin_family = AF_INET;                  // 协议族(IPv4)  
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);   // 绑定所有本地IP(INADDR_ANY)  
    serv_addr.sin_port = htons(8080);                // 端口号(需转换为网络字节序)  
    
  • addrlen:地址结构体的大小(sizeof(struct sockaddr_in))。
关键细节:
  • INADDR_ANY:表示绑定本地所有网络接口的IP(如服务器有多个网卡时,可接收任意网卡的连接)。
  • 端口号范围:0~65535,其中 0~1023 是知名端口(如HTTP 80),建议使用 1024~65535 避免冲突。

3. 监听连接:listen()

功能:将套接字设置为监听状态,允许接收客户端连接请求。

int listen(int sockfd, int backlog);  
参数说明:
  • sockfd:已绑定的套接字描述符(监听套接字)。
  • backlog:未完成连接队列的最大长度(处于 SYN_RCVD 状态的连接数),超过则新连接被拒绝(Linux通常建议设为 5~10,具体受系统限制)。
注意:

listen() 仅标记套接字为监听状态,不主动接收连接,需配合 accept() 使用。

4. 接受连接:accept()

功能:从监听队列中取出一个已完成的连接请求,返回一个新的套接字描述符(用于与该客户端通信)。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);  
参数说明:
  • sockfd:监听套接字描述符(listen() 后的套接字)。
  • addr:输出参数,存储客户端的IP和端口信息(需提前分配空间)。
  • addrlen:输入输出参数,传入 addr 大小,返回实际存储的地址长度。
核心特性:
  • 阻塞性:若没有客户端连接,accept() 会一直阻塞等待。
  • 新套接字:返回的新描述符是“通信套接字”,用于与客户端收发数据;原监听套接字仍继续监听新连接。

5. 客户端连接:connect()

功能:客户端向服务器发起连接请求,完成TCP三次握手。

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);  
参数说明:
  • sockfd:客户端创建的套接字描述符。
  • addr:服务器的地址信息(需填充服务器IP和端口,端口和IP需转换为网络字节序)。
  • addrlen:服务器地址结构体的大小。
示例:客户端连接服务器
struct sockaddr_in serv_addr;  
serv_addr.sin_family = AF_INET;  
serv_addr.sin_port = htons(8080);  
// 将点分十进制IP转换为网络字节序二进制  
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);  // 发起连接  
if (connect(client_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {  perror("连接失败");  exit(1);  
}  

6. 数据交互:send()/recv()read()/write()

TCP通信中,数据通过套接字的读写缓冲区传输,常用函数如下:

函数原型功能
send()ssize_t send(int sockfd, const void *buf, size_t len, int flags);发送数据到套接字缓冲区
recv()ssize_t recv(int sockfd, void *buf, size_t len, int flags);从套接字缓冲区接收数据
write()ssize_t write(int fd, const void *buf, size_t count);等同于 send(flags=0)
read()ssize_t read(int fd, void *buf, size_t count);等同于 recv(flags=0)
参数说明:
  • sockfd/fd:通信套接字描述符(accept()connect() 返回的描述符)。
  • buf:数据缓冲区(发送时存数据,接收时存结果)。
  • len/count:数据长度(字节)。
  • flags:传输标志(通常为 0,表示默认行为)。
核心特性:
  • 阻塞性:若缓冲区满(发送)或空(接收),函数会阻塞等待。
  • 返回值:成功返回实际传输的字节数;0 表示连接关闭;-1 表示出错。

7. 关闭连接:close()

功能:关闭套接字,释放资源,触发TCP四次挥手。

int close(int fd);  
  • 服务器需关闭 通信套接字(与客户端的连接)和 监听套接字(停止接收新连接)。
  • 客户端关闭套接字后,会向服务器发送 FIN 包,终止连接。

三、核心基础概念

1. 网络字节序

不同计算机的字节存储顺序(大端/小端)不同,TCP协议规定网络中必须使用 大端字节序(高位字节存低地址),需通过转换函数统一格式:

函数功能适用场景
htons()主机字节序 → 网络字节序(16位)端口号转换(short
htonl()主机字节序 → 网络字节序(32位)IP地址转换(int
ntohs()网络字节序 → 主机字节序(16位)解析端口号
ntohl()网络字节序 → 主机字节序(32位)解析IP地址
示例:端口和IP转换
uint16_t port = 8080;  
uint16_t net_port = htons(port);  // 主机→网络(端口)  uint32_t ip = inet_addr("192.168.1.1");  // 点分十进制→网络字节序(IPv4)  

2. IP地址格式转换

IP地址在代码中需在“点分十进制字符串”和“二进制整数”间转换,常用函数:

函数功能适用协议
inet_addr()点分十进制字符串 → 网络字节序整数IPv4(过时)
inet_ntoa()网络字节序整数 → 点分十进制字符串IPv4(非线程安全)
inet_pton()字符串 → 二进制(支持IPv4/IPv6)现代推荐
inet_ntop()二进制 → 字符串(支持IPv4/IPv6)现代推荐
现代用法示例:
// 字符串→二进制(IPv4)  
struct in_addr ip_bin;  
inet_pton(AF_INET, "127.0.0.1", &ip_bin);  // 二进制→字符串(IPv4)  
char ip_str[INET_ADDRSTRLEN];  
inet_ntop(AF_INET, &ip_bin, ip_str, INET_ADDRSTRLEN);  
printf("IP: %s\n", ip_str);  // 输出 "127.0.0.1"  

3. 文件描述符与缓冲区

  • 服务器的两个套接字描述符
    • 监听套接字(listen() 后的fd):仅用于接收新连接,不参与数据交互。
    • 通信套接字(accept() 返回的fd):每个客户端连接对应一个,用于收发数据。
  • 缓冲区机制:每个套接字对应内核中的 读缓冲区写缓冲区
    • 发送数据:send()/write() 将数据写入写缓冲区,内核异步发送到网络。
    • 接收数据:内核将网络数据存入读缓冲区,recv()/read() 从缓冲区读取。
    • 缓冲区满时:send() 阻塞(直到有空间);缓冲区空时:recv() 阻塞(直到有数据)。

四、TCP粘包问题及解决方案

什么是粘包?

TCP是流式传输,数据无边界,若发送方连续发送小数据包,接收方可能将多个数据包合并为一个“大数据块”,导致无法区分边界(如发送“hi”和“jack”,接收方可能收到“hijack”)。

粘包原因

  • 发送方:数据太小,内核合并发送(Nagle算法)。
  • 接收方:数据到达速度快于处理速度,缓冲区累积多个数据包。

解决方案:固定格式分包

核心思路:先发送数据长度,再发送实际数据,接收方按长度解析。

步骤示例:
  1. 发送方

    • 将数据长度(len)转换为网络字节序,先发送 len(4字节整数)。
    • 再发送长度为 len 的实际数据。
    // 发送"hello"(长度5)  
    int len = htonl(5);  // 长度转换为网络字节序  
    send(fd, &len, 4, 0);       // 先发送长度  
    send(fd, "hello", 5, 0);    // 再发送数据  
    
  2. 接收方

    • 先读取4字节获取数据长度 len(转换为主机字节序)。
    • 再读取 len 字节的实际数据。
    int len;  
    recv(fd, &len, 4, 0);       // 先读长度  
    len = ntohl(len);           // 转换为主机字节序  
    char buf[len];  
    recv(fd, buf, len, 0);      // 再读实际数据  
    

五、跨平台差异(Windows环境)

Windows套接字编程与Linux有以下核心区别:

  1. 头文件和库

    #include <winsock2.h>       // 核心头文件  
    #pragma comment(lib, "ws2_32.lib")  // 链接套接字库  
    
  2. 初始化和清理

    // 初始化套接字库  
    WSADATA wsaData;  
    WSAStartup(MAKEWORD(2, 2), &wsaData);  // 程序结束时清理  
    WSACleanup();  
    
  3. 函数差异

    • 关闭套接字用 closesocket() 而非 close()
    • 错误码获取用 WSAGetLastError() 而非 errno

六、高频面试考点总结

  1. TCP通信核心流程

    • 服务器:socket() 创建套接字 → bind() 绑定IP和端口 → listen() 监听连接 → accept() 阻塞等待客户端连接 → read()/write() 数据交互 → close() 关闭连接。
    • 客户端:socket() 创建套接字 → connect() 发起连接 → read()/write() 数据交互 → close() 关闭连接。
  2. INADDR_ANY 的作用
    绑定服务器本地所有网络接口的IP地址(如服务器有多个网卡时),使服务器能接收来自任意网卡的连接请求,无需硬编码具体IP,增强灵活性。

  3. listen()backlog 的含义
    表示未完成连接队列(处于 SYN_RCVD 状态)的最大长度,超过该值的新连接会被拒绝。实际有效长度可能受系统内核参数(如 net.core.somaxconn)限制。

  4. accept() 的特性

    • 阻塞性:无新连接时会一直阻塞,直到有客户端连接或被信号中断。
    • 返回新套接字:accept() 返回的是与客户端通信的套接字,原监听套接字仍可继续接收其他连接(实现多客户端通信需多线程/多进程)。
  5. 网络字节序与转换函数

    • 网络字节序为 大端字节序,主机字节序可能为大端或小端(取决于CPU架构)。
    • 必须转换的场景:端口号(htons()/ntohs())、IP地址(htonl()/ntohl())。
    • 现代推荐用 inet_pton()/inet_ntop() 转换IP地址(支持IPv4/IPv6,线程安全)。
  6. TCP粘包问题

    • 原因:TCP是流式传输,无数据边界,多个小数据包可能被合并传输。
    • 解决方案:长度前缀法(先发送数据长度,再发送实际数据,接收方按长度解析)。
  7. 套接字缓冲区机制

    • 每个套接字对应内核中的读缓冲区和写缓冲区,数据通过缓冲区间接传输。
    • send()/write() 成功仅表示数据写入写缓冲区,不代表已发送到对端;recv()/read() 从读缓冲区取数据,缓冲区为空时阻塞。
  8. 文件描述符的角色

    • 服务器有两类描述符:监听描述符(负责接收连接)和 通信描述符(每个客户端一个,负责数据交互)。
    • 描述符是内核管理套接字的索引,关闭描述符会触发TCP四次挥手释放连接。

总结

TCP套接字编程的核心是理解“连接建立→数据交互→连接关闭”的全流程,掌握 socket()/bind()/listen()/accept()/connect() 等API的参数和特性,以及网络字节序、粘包处理等细节。实际开发中需注意跨平台差异(如Windows的 WSAStartup()),并通过多线程/IO复用等技术实现高效的多客户端通信。这些基础是网络编程的核心。

http://www.dtcms.com/wzjs/616562.html

相关文章:

  • 铺面怎样做放上网站wordpress 被写入文件
  • 茂名快速建站模板品牌营销推广
  • 南京手机app开发公司如何网站关键词优化
  • 建什么网站收益比较号秦皇岛网站开发公司
  • 最容易做的网站类型网站构建技术
  • 上海网站se0优化公司wordpress 4.7 新功能
  • 建设通是个什么网站秦皇岛解封最新消息今天
  • 学习网站开发教程建设网站建设多少钱
  • 服饰网站建设技术方案网站开发绑定微信qq注册
  • 网络公司 建站 官方网站网站长期建设运营计划书
  • 网站建设有哪些需求福州网站排名
  • 品牌网站有哪些内容中国核工业第五建设有限公司地址
  • 邢路桥建设总公司网站做网站无需备案
  • 自己做的网站为何手机不能浏览手机软件开发工程师
  • 企业网站建设品牌新网站怎么做才能让搜狗收录
  • 学校网站建设问卷调查表wordpress _e
  • 网站开发有哪些方向方维网站后台提示验证码错误
  • 在哪里找做网站的客户Wordpress主题更改导航栏颜色
  • 软件网站排行榜手机网站建站APP
  • 个人备案的域名可以做网站吗wordpress文章顶置
  • 公司网站建设ppt龙之向导外贸网站
  • 赤峰建设业协会的官方网站官网建设多少钱
  • 校车网站建设创新创意产品设计方案
  • 网站文章编辑器代码网站建设和网站
  • 个人博客网站页面樟木头镇网站仿做
  • 汕头企业网站建设东莞网站建设和制作
  • 个人博客网站的建设结构图宁波网络公司电话
  • 男的直接做的视频网站网页设计代码居中
  • 网站怎么做流量统计东莞横沥
  • 中国十大设计素材网站长沙seo培训班