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

网站建设一般字体多大seo初学教程

网站建设一般字体多大,seo初学教程,网站制作前期,用凡科网建设的网站和用dreamweaver建设的网站有什么不一样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/25906.html

相关文章:

  • 教育机构网站建设方案google官网入口
  • 网站架构建设福州短视频seo获客
  • wordpress可以建立多个站点短视频营销推广策略
  • 开发网站广州网页入口网站推广
  • b站推广入口在哪里正规电商平台有哪些
  • 四川省建设厅资格注册中心网站网站推广方法
  • 网站功能设计100个商业经典案例
  • 上海专业网站设计刷关键词优化排名
  • 做网站价格报价费用多少钱足球比赛今日最新推荐
  • 在vs做的项目怎么连接到网站站长工具传媒
  • vultr做网站怎么样seo优化的常用手法
  • 网站建设价格报价360投放广告怎么收费
  • 建设一个网站需要哪些迅雷磁力链bt磁力天堂下载
  • 网站开发用到的技术百度地图人工客服电话
  • 今科网站建设公司百度首页关键词优化
  • wordpress自动更新文章百度排名优化咨询电话
  • 网站建设每天的工作媒体软文推广平台
  • 如何在搜索引擎做网站能翻到国外的浏览器
  • 合肥网站建设创优西安seo公司哪家好
  • 酷乐家居在线设计白杨seo教程
  • 网店美工的岗位职责惠州seo计费
  • 企业手机网站建seo排名哪家正规
  • 学校的网站如何建设网页seo是什么意思
  • 医疗网站seo怎么做b站2023推广网站
  • web前端开发培训机构哪个好无锡seo排名收费
  • 深圳搜索营销win7一键优化工具
  • 做网站架构需要什么工具品牌宣传推广方案
  • 新乡专业做淘宝网站创新营销方式有哪些
  • 成都关键词优化济南seo优化外包服务公司
  • 网站建设找天宇智能无代码建站