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

Linux30 网络编程TCP流程

5.Socket网络编程

5.1Socket 核心概念

1. 什么是 Socket?

Socket 是 “IP 地址 + 端口号 + 传输协议” 的组合,唯一标识网络中的一个通信进程(比如 “192.168.1.100:8080/TCP” 对应电脑上的某个服务程序)。

类比:Socket 就像 “电话”,IP 地址是 “电话号码”,端口号是 “分机号”,传输协议(TCP/UDP)是 “通话规则”。

5.2Socket编程流程

5.2.1 TCP 编程流程(面向连接,可靠传输)

TCP 需先建立连接(三次握手),再传输数据,最后断开连接(四次挥手),流程类似 “打电话”:

服务端(被动监听,等待客户端连接)
  1. 创建 Socket:创建 TCP 类型的 Socket 端点。
  1. 绑定地址(bind):将 Socket 与 “IP 地址 + 端口号” 绑定(确定服务端的通信地址)。
  1. 监听连接(listen):将 Socket 设为 “监听模式”,等待客户端连接。
  1. 接受连接(accept):阻塞等待客户端连接,连接成功后返回新的 Socket(用于与该客户端通信)。
  1. 收发数据(read/send):通过新 Socket 与客户端双向传输数据。
  1. 关闭连接(close):通信结束后,关闭 Socket 释放资源。
客户端(主动发起连接)
  1. 创建 Socket:创建 TCP 类型的 Socket 端点。
  1. 连接服务端(connect):主动向服务端的 “IP + 端口” 发起连接。
  1. 收发数据(read/send):连接成功后,与服务端双向传输数据。
  1. 关闭连接(close):通信结束后,关闭 Socket。
服务端:socket() → bind() → listen() → accept() → read()/write() → close()↑客户端:socket() → connect() → read()/write() → close()

5.3TCP连接函数详解

5.3.1创建套接字socket函数

函数功能:创建一个用于网络通信的套接字(Socket),返回套接字描述符(类似文件描述符,用于后续网络操作)。

参数取值与含义
domain协议族,如AF_INET(IPv4)、AF_INET6(IPv6)、AF_UNIX(本地进程间通信)
type套接字类型,如SOCK_STREAM(流式,TCP)、SOCK_DGRAM(数据报,UDP)
protocol协议,通常为 0(表示使用type对应的默认协议,如SOCK_STREAM默认 TCP)
  • 成功:返回非负套接字描述符(用于bindconnect等后续操作)。

  • 失败:返回 - 1,可通过errno查看错误原因。

Socket 类型对应协议特点适用场景
SOCK_STREAMTCP面向连接、可靠传输、字节流、无边界网页、文件传输、登录验证(需确保数据完整)
SOCK_DGRAMUDP无连接、不可靠、数据报(有边界)视频、语音、实时游戏(允许少量丢包,追求速度)
5.3.2绑定套接字与地址bind函数

函数功能:将套接字描述符sockfd与指定的网络地址addr绑定,使套接字能通过该地址接收网络请求(服务器端必须调用,客户端通常可选)。

  • 成功:返回 0。

  • 失败:返回 - 1,可通过errno查看错误原因(如地址已被占用、权限不足等)

参数含义与要求
sockfd套接字描述符(由socket函数创建返回)
addr指向sockaddr结构体的指针,需根据协议族(如 IPv4/IPv6)填充具体地址信息(如 IP、端口)
addrlenaddr结构体的长度(字节数),用于告知内核地址结构的大小
维度IPv4IPv6
协议族AF_INETAF_INET6
地址结构体struct sockaddr_instruct sockaddr_in6
地址表示32 位(如192.168.1.1128 位(如::1表示本地回环)
作用域 ID本地链路地址需设置sin6_scope_id

bind是服务器端启动流程的核心步骤之一:只有绑定地址后,套接字才能 “监听” 该地址上的连接请求(通过listen函数)。它确保了客户端能通过明确的 IP 和端口找到服务器,是 TCP/UDP 通信中 “地址寻址” 的基础。

5.3.3将套接字转为被动监听状态listen函数

函数功能:将通过socket创建、bind绑定的套接字,转为被动监听状态,开始接收客户端的连接请求。

参数含义与要求
sockfd套接字描述符(需先通过socket创建、bind绑定)
backlog监听队列的最大长度(客户端连接请求的等待队列长度,实际有效长度由系统内核限制,通常设为510等合理值)
  • 成功:返回0

  • 失败:返回-1,可通过errno查看错误原因(如套接字未绑定、状态非法等)。

listen是服务器端 “接收连接” 流程的核心:调用后,套接字会维护一个半连接队列(客户端发起连接但未完成三次握手的请求)和全连接队列(已完成三次握手、等待服务器accept的请求),backlog参数控制全连接队列的最大长度。只有通过listen,服务器才能用accept函数从队列中取出并处理客户端的连接请求。

5.3.4接收客户端连接的accept4函数

函数功能:从监听套接字的全连接队列中取出一个客户端连接,返回新的套接字描述符(用于与该客户端通信),同时可获取客户端的地址信息。

参数含义与要求
sockfd监听套接字描述符(需先通过socketbindlisten初始化)
addr指向sockaddr结构体的指针,用于存储客户端的地址信息(若为NULL,则不获取地址)
addrlen指向socklen_t变量的指针,输入时为addr结构体的长度,输出时为实际填充的长度
flags标志位,可选项如SOCK_NONBLOCK(将新套接字设为非阻塞)、SOCK_CLOEXEC(执行 exec 时关闭套接字)
  • 成功:返回新的套接字描述符(用于与客户端通信)。

  • 失败:返回-1,可通过errno查看错误原因(如无连接可接受、参数非法等)。

accept4accept的扩展,通过flags参数支持非阻塞模式和文件描述符的自动关闭(CLOEXEC),更适配现代网络编程的高性能、高安全性需求。它是服务器端 “建立连接” 流程的最后一步,调用后服务器即可通过新套接字与客户端进行数据收发。

5.3.5客户端连接服务器connect函数

函数功能:客户端通过connect函数向服务器发起 TCP 连接请求,触发 TCP 三次握手流程,建立端到端的通信链路。

参数含义与要求
sockfd客户端套接字描述符(由socket函数创建,未连接状态)
addr指向sockaddr结构体的指针,需填充服务器的 IP 地址和端口(如struct sockaddr_in用于 IPv4)
addrlenaddr结构体的长度(字节数),通常用sizeof(struct sockaddr_in)获取
  • 成功:返回0,TCP 三次握手完成,连接建立。

  • 失败:返回-1,可通过errno查看错误原因(如ECONNREFUSED表示服务器拒绝连接、ETIMEDOUT表示连接超时)。

5.3.6从已连接套接字接收数据recv函数

函数功能:从已建立连接的套接字(如 TCP 连接)中接收数据,将数据存入指定缓冲区。

参数含义与要求
sockfd已连接的套接字描述符(如accept返回的服务端客户端套接字、connect后的客户端套接字)
buf存储接收数据的缓冲区指针
len缓冲区长度(字节数)
flags标志位,常见取值0(阻塞接收),也可设MSG_DONTWAIT(非阻塞)、MSG_PEEK(预览数据不删除)等
5.3.7发送网络数据的send函数

函数功能:向套接字发送数据,支持 TCP 流式发送和 UDP 数据报发送(需结合套接字类型)。

参数含义与要求
sockfd套接字描述符(已连接的 TCP 套接字或未连接的 UDP 套接字均可)
buf待发送数据的缓冲区指针(const 修饰表示数据只读)
len待发送数据的长度(字节数)
flags标志位,常见取值0(默认发送),也可设MSG_DONTWAIT(非阻塞发送)、MSG_OOB(发送带外数据)等
  • 成功:返回实际发送的字节数(≥0)。

  • 失败:返回-1,可通过errno查看错误原因(如EAGAIN表示非阻塞时发送队列满)。

5.4TCP网络编程连接示例

服务器端代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main(){int sersockfd=socket(AF_INET,SOCK_STREAM,0);//地址族 选择socket类型TCP/UDP 协议if(sersockfd==-1){exit(1);}struct sockaddr_in saddr,caddr;//saddr存储服务器地址 caddr存储客户端地址memset(&saddr,0,sizeof(saddr));saddr.sin_family=AF_INET;saddr.sin_port=htons(6000);saddr.sin_addr.s_addr=inet_addr("127.0.0.1");int n=bind(sersockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(n==-1){close(sersockfd);exit(1);}n=listen(sersockfd,5);if(n==-1){close(sersockfd);exit(1);}int len=sizeof(caddr);int cilsockfd=accept(sersockfd,(struct sockaddr*)&caddr,&len);if(cilsockfd<0){close(cilsockfd);exit(1);}printf("accept sockfd =%d port=%d ip=%s\n",cilsockfd,ntohs(caddr.sin_port),inet_ntoa(caddr.sin_addr));if(cilsockfd==0){printf("cilent close\n");close(cilsockfd);exit(1);}char buff[128]={0};printf("input:");fgets(buff,128,stdin);int byte=send(cilsockfd,buff,sizeof(buff),0);memset(buff,0,sizeof(buff));byte=recv(cilsockfd,buff,127,0);printf("recv=%s\n",buff);close(sersockfd);close(cilsockfd);exit(0);
}

客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 地址族 选择socket类型TCP/UDP 协议if (sockfd == -1){exit(1);}struct sockaddr_in saddr; // saddr存储服务器地址memset(&saddr, 0, sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("127.0.0.1");int c = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));if (c == -1){exit(1);}char buff[128] = {0};int byte = recv(sockfd, buff, 127, 0);printf("buff=%s\n", buff);byte = send(sockfd, "ok", 2, 0);close(sockfd);exit(0);
}

结果示例:

http://www.dtcms.com/a/586247.html

相关文章:

  • 多线程——volatile 关键字 wait 和 notify
  • 江苏网站建设南通西宁 专业网站建设
  • Python:np.clip(z, -250, 250) 的功能解释
  • 从零开始打造 Laravel 扩展包:开发、测试到发布完整指南
  • 网站建设文案中国建设银行官网app
  • 网站备案 怎么加做外贸网站流程图
  • 深入浅出红黑树:C++ 完整实现与核心原理剖析
  • 制作论坛类网站模板node.js做网站好累
  • 浙江网站制作dede音乐网站
  • Mediatek NeuroPilot Yolov8量化
  • 使用renren-generator逆向生成增删改查代码
  • 北京网站建设一条龙昆明岭蓝网站建设公司
  • 1.PagedAtteion算法
  • 网站开发语言怎么看如何做网站授权网址
  • 上上海网站建设设计网站快速收录软件
  • 购物网站开发模板做卷闸门网站有用吗
  • [Linux][经验总结]Nginx报错:unknown directive “sub\_filter“ 解决与优化
  • cesium126,230420,程序运行时动态加载本地倾斜摄影:使用 C++ 编程
  • 男孩子怎么做网站赚钱wordpress 文章转义
  • DevEco Studio 查看 previewer 里 console.log 的日志
  • 天津河东做网站贵吗青岛网站设计公司联系方式
  • SpringBoot面试题04-BeanDefinition
  • 电脑网站怎么创建到桌面上讲课app怎么制作
  • 东莞网站建设怎么收费wordpress中文分享插件下载
  • CosyVoice 2 部署加速推理模型(Ubuntu 24.04)
  • 【C++初阶】string类的模拟实现
  • 学做网站根学ps有前途吗网站建设费 科目
  • 铁岭做网站包括哪些微信运营工具
  • GUI自动化测试--自动化简单示例
  • 深圳住房建设厅网站首页seop