Linux网络编程_常见API

Linux网络编程 OSI七层参考模型:应用层 表示层 会话层 传输层 网络层 数据链路层 物理层随着时间的发展:后面又出现了四层参考模型:应用层 传输层 网络层 网络接口层应用层协议:http SMTPTCP/IP协议族的每一层的作用--重点:网络接口层:负责将二进制数据流转化成对应的数据帧,并进行数据帧的发送和接收。(网络中传输的方式)网络层:负责将数据帧封装成IP数据报,并运行对应的路由算法(数学--拉格朗日特勒傅里叶)。 阅读详情

下面我给你逐行详细拆解这 5 个 socket 核心 API,讲清它们的作用、参数含义、返回值、使用场景和关键细节,帮你彻底搞懂 TCP 网络编程的核心流程。


1. socket() —— 创建套接字(客户端 + 服务器都要用)

作用

创建一个套接字文件描述符(相当于网络通信的 “句柄”),是网络编程的第一步。它定义了通信的地址族、套接字类型、协议类型。

函数原型

int socket(int domain, int type, int protocol);

参数详解

参数含义常用取值
domain地址族(通信域),决定用哪种网络协议AF_INET:IPv4 网络AF_INET6:IPv6 网络AF_UNIX:本地进程间通信(Unix 域)
type套接字类型,决定通信的特性SOCK_STREAM:TCP(面向连接、可靠、字节流)SOCK_DGRAM:UDP(无连接、不可靠、数据报)SOCK_RAW:原始套接字(直接操作 IP 层)
protocol具体协议,一般填 0 让系统自动匹配0:自动匹配(TCP 对应 IPPROTO_TCP,UDP 对应 IPPROTO_UDP)IPPROTO_TCP:显式指定 TCPIPPROTO_UDP:显式指定 UDP

返回值

  • 成功:返回非负整数(套接字文件描述符 sockfd)
  • 失败:返回 -1,可通过 perror() 打印错误信息

关键要点

  • 客户端和服务器都必须先调用 socket(),拿到 sockfd 才能进行后续操作。
  • SOCK_STREAM 对应 TCP,SOCK_DGRAM 对应 UDP,这是最常用的两种类型。

示例

// 创建 IPv4 的 TCP 套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
    perror("socket failed");
    exit(1);
}

2. bind() —— 绑定地址(服务器端专用)

作用

将套接字 sockfd 与一个具体的 IP 地址 + 端口号绑定,让客户端能通过这个地址找到服务器。客户端一般不需要 bind()(系统会自动分配临时端口)。

函数原型

int bind(int socket, const struct sockaddr *address, socklen_t address_len);

参数详解

参数含义关键说明
socket要绑定的套接字 sockfd即 socket() 返回的文件描述符
address指向地址结构体的指针通用结构体 struct sockaddr,实际用 struct sockaddr_in(IPv4),需强制转换
address_len地址结构体的长度填 sizeof(struct sockaddr_in)

关键细节(必看)

  1. 地址结构体 struct sockaddr_in(IPv4 专用)

    struct sockaddr_in {
        sa_family_t    sin_family;   // 地址族,必须填 AF_INET
        in_port_t      sin_port;     // 端口号,需用 htons() 转网络字节序
        struct in_addr sin_addr;     // IP 地址
        char           sin_zero[8];  // 填充位,全填 0
    };
    
    • sin_port:端口号,必须用 htons() 转换(主机字节序 → 网络字节序,大端序)。
    • sin_addr.s_addr:IP 地址,常用 INADDR_ANY(监听本机所有网卡的 IP,如 127.0.0.1、局域网 IP 等)。
  2. 网络字节序转换

    • 端口 / IP 必须转网络字节序:htons()(端口)、htonl()(IP)
    • 接收时转主机字节序:ntohs()(端口)、ntohl()(IP)

返回值

  • 成功:返回 0
  • 失败:返回 -1(常见错误:端口被占用、权限不足)

示例

struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));  // 清空结构体
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);          // 绑定 8080 端口,转网络字节序
serv_addr.sin_addr.s_addr = INADDR_ANY;    // 监听所有网卡

// 绑定套接字
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
    perror("bind failed");
    exit(1);
}

3. listen() —— 开启监听(TCP 服务器专用)

作用

将 bind() 后的套接字从 “主动套接字” 转为 “被动监听套接字”,让服务器开始等待客户端的连接请求。UDP 不需要 listen()(无连接,无需监听)。

函数原型

int listen(int socket, int backlog);

参数详解

参数含义说明
socket监听的套接字 sockfd即 bind() 后的套接字
backlog等待连接的队列长度指全连接队列的最大长度(已完成三次握手、等待 accept() 的连接数),不同系统有上限(如 Linux 一般最大 128)

返回值

  • 成功:返回 0
  • 失败:返回 -1

关键要点

  • 仅 TCP 服务器需要调用,调用后套接字进入监听状态。
  • backlog 不是 “最大连接数”,而是 “等待被接受的连接数”,实际最大连接数受系统资源限制。

示例

// 开启监听,队列长度 5
if (listen(sockfd, 5) == -1) {
    perror("listen failed");
    exit(1);
}

4. accept() —— 接受连接(TCP 服务器专用)

作用

从监听队列中取出一个客户端连接,并创建一个新的套接字(用于和该客户端单独通信)。原监听套接字继续保持监听状态,可接受其他客户端。UDP 不需要 accept()(无连接,无需建立连接)。

函数原型

int accept(int socket, struct sockaddr* address, socklen_t* address_len);

参数详解

参数含义关键说明
socket监听套接字 sockfd即 listen() 后的套接字
address输出参数用于存储客户端的地址信息(IP + 端口),不需要可填 NULL
address_len输入输出参数传入时填 address 结构体的长度,返回时填实际长度,不需要可填 NULL

返回值

  • 成功:返回新的连接套接字 connfd(专门用于和该客户端通信)
  • 失败:返回 -1

关键要点

  • accept() 是阻塞函数:若无客户端连接,会一直阻塞,直到有连接到来。
  • 新的 connfd 是独立的套接字,服务器通过它和客户端收发数据,原 sockfd 继续监听。
  • 多客户端场景:服务器需循环调用 accept(),或用多线程 / IO 多路复用(select/poll/epoll)处理。

示例

struct sockaddr_in cli_addr;
socklen_t cli_len = sizeof(cli_addr);

// 接受客户端连接,阻塞等待
int connfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
if (connfd == -1) {
    perror("accept failed");
    exit(1);
}

// 打印客户端 IP 和端口
printf("client connected: %s:%d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));

5. connect() —— 建立连接(TCP 客户端专用)

作用

客户端主动向服务器发起连接请求,完成 TCP 三次握手,建立可靠连接。UDP 不需要 connect()(无连接,可直接 sendto()/recvfrom() 通信)。

函数原型

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数详解

参数含义说明
sockfd客户端的套接字 sockfd即客户端 socket() 创建的套接字
addr服务器的地址结构体需填服务器的 IP + 端口,同样用 struct sockaddr_in,强制转换为 struct sockaddr*
addrlen地址结构体的长度填 sizeof(struct sockaddr_in)

返回值

  • 成功:返回 0(连接建立完成)
  • 失败:返回 -1(常见错误:服务器未启动、IP / 端口错误、网络不通)

关键要点

  • 仅 TCP 客户端需要调用,调用后客户端和服务器的连接就建立了。
  • 客户端无需 bind(),系统会自动分配临时端口。
  • connect() 也是阻塞函数,直到连接成功或失败。

示例

struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);          // 服务器端口
// 服务器 IP,这里用 127.0.0.1(本地回环)
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
    perror("inet_pton failed");
    exit(1);
}

// 连接服务器
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
    perror("connect failed");
    exit(1);
}

总结:TCP 客户端 / 服务器的完整流程

服务器端(TCP)

  1. socket() → 创建监听套接字
  2. bind() → 绑定 IP + 端口
  3. listen() → 开启监听
  4. accept() → 接受客户端连接,得到通信套接字
  5. read()/write()(或 recv()/send())→ 和客户端通信
  6. close() → 关闭套接字

客户端(TCP)

  1. socket() → 创建客户端套接字
  2. connect() → 连接服务器
  3. read()/write()(或 recv()/send())→ 和服务器通信
  4. close() → 关闭套接字

UDP 简化流程(无连接)

  • 服务器:socket() → bind() → recvfrom()/sendto()
  • 客户端:socket() → sendto()/recvfrom()(无需 connect())

Linux 网络编程套接字 在每一个IP数据包的首部(Header)中,包含两个关键字段:源IP地址(Source IP Address) 和 目标IP地址(Destination IP Address),它们共同标识了数据包的发送方和接收方。UDP(用户数据报协议)是一个轻量级的传输层协议,它和 TCP 一样,也建立在 IP 协议之上。网络编程中的地址转换函数主要用于 字符串地址(如 "127.0.0.1") 和二进制地址(如 in_addr 结构体)之间的相互转换,它们常用于设置 socket 地址和打印对端地址。 阅读详情

相关推荐

linux c socket api

讲述了linux中socket编程常用的函数,是linux c socket编程必须用到的。

【Linux】socket基础API

1. 创建socket 2. 绑定socket地址 3. 监听socket 4. 接受连接 5. 发起连接 6. 关闭连接 7. 数据读写 8. 基于UDP的回声程序 9. 基于TCP的回声程序

Qiuhan_909的博客 1658

IsaacLab从入门到精通(二) 导入自定义机器人

IsaacLab系列第二讲,导入自定义的机器人及设置

DejaWu33的博客 8463

Linux下socketAPI的使用,实现udp和tcp通信

/ 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)一个文件描述符,执行socket()函数创建套接字的时候,相当于把网络以文件的形式打开了。创建失败就返回小于0的数// 绑定端口号 (TCP/UDP, 服务器)如果绑定成功返回0,绑定失败返回-1注意:bind(sock, (struct sockaddr*)&local, sizeof(local))传入第二个参数的时候需要进行强转。

Zebra的博客 2092

接口自动化测试如何做?测试老鸟总结,接口测试数据构造大全......

接口参数的数据获取:接口文档:接口文档通常会包含接口需要的请求参数和返回结果的格式、类型等信息;测试用例设计:根据测试用例设计的需求,可以确定需要哪些请求参数以及期望的响应结果;业务数据:从实际业务场景中获取数据,以确保测试数据的真实性和代表性;数据库:从数据库中获取数据,作为接口测试的输入参数;随机数据生成器:通过随机数据生成器生成测试数据,以增加测试用例的多样性和覆盖率。在选择数据来源时,需要根据具体情况进行选择。如果有可靠的接口文档,可以直接从文档中获取请求参数和预期结果;

798

AArch64 ARM64 寄存器介绍

除了上述通用寄存器,还有FPSR(浮点状态寄存器)和 FPCR(浮点控制寄存器)等。X29寄存器和X30寄存器在函数调用和堆栈帧的管理中扮演着关键角色。AArch64架构提供了31个通用寄存器,每个寄存器都可以用作64位X寄存器(X0~X30)或32位W寄存器(W0~W30)。使用X寄存器将导致64位的计算,使用W寄存器将导致32位的计算。EL0、EL1、EL2和EL3是AArch64架构中定义的四个特权级别(Exception Levels),用于支持不同的执行环境和特权级别。

lml435035844的博客 1万+

Linux网络编程——Socket编程步骤及常用API

内核为每个由服务器进程接受的客户连接创建一个已连接套接字(表示 TCP 三次握手已完成),当服务器完成对某个给定客户的服务时,相应的已连接套接字就会被关闭。模式,listen 函数只用于服务器端,服务器进程不知道要与谁连接,因此,它不会主动此要求与某个进程连接,只是一直监听是否有其他客户进程与之连接,然后响应该连接清求,并对它做出处理,UDP:数据报套接字定义了一种无连按的服,数据通过相互独立的报文进行传输, 是无序的,并且不保证是可靠,无差错的。服务器调用,用于从已完成连接队列队头返回下一个已完成连接。

2301_78772787的博客 1237

基于物联网设计的蜂箱智能监测系统设计

为解决传统养蜂业依赖人工、管理效率低下、干扰蜂群等问题,本项目设计并实现了一套基于物联网(IoT)的蜂箱智能监测系统。

679

Unix/Linux编程: Socket API

socket /* * 功能: 指明通信类型 * 参数: * domain: 通信域 * type:类型 * protocal:通信范围 * 返回值: * 如果正确,返回一一个非负int类型的值,表示该socket实例唯一标识符的文件描述符。这个值可以调用其他系统调用来进行各种操作,比如绑定和监听端口、发送数据等 */ int socket(int domain, int type, int protocol) domain取值: domain 说明 AF_IN

OceanStar的博客 1063

Android Camera驱动开发工程师面试指南:技术深度与实战准备

摘要:上海移远通信招聘Android Camera驱动开发工程师,主要负责Camera传感器驱动开发维护、高通/展锐平台底层开发及技术预研。岗位要求1年以上嵌入式开发经验,精通Camera传感器驱动调试,熟悉高通平台Camera架构及Android HAL框架。具备HAL开发、算法集成或车载/支付行业经验者优先。工作内容以Driver/HAL开发为主,需具备硬件接口评估能力。该职位接受Linux/单片机背景人员转型。

郑伟强dev的专栏 280

Spring AI Alibaba 项目源码学习(九)-其他继承BaseAgent

本文分析了Spring AI Alibaba Agent Framework中的A2aRemoteAgent实现,主要特点包括: 实现了Agent间的远程调用能力,支持分布式部署 核心组件包括AgentCard封装元数据、A2aNodeActionWithConfig处理调用逻辑、AgentCardProvider提供卡片管理 支持流式调用和状态共享机制 采用Builder模式构建Agent实例 通过指令传递实现Agent间通信 关键流程包括状态提取、请求构建、远程调用和状态更新四个步骤,形成Agent

819

Linux中socket地址API

学习《Linux高性能服务器编程》第五章Linux网络编程基础API,为了印象深刻一些,多动手多实践,所以记下这个笔记。这一篇主要记录Linux中socket地址的基础,包括主机字节序和网络字节序、socket地址和IP地址转化函数。.........

bugcat的博客 676

【软考高级架构】案例题考前突击6——大数据架构

前一类的数据主要由流量方以接口的方式提供(比如对接的腾讯广点通平台),后一类则是某网特有的数据,通过买家的浏览、下单、付款日志算出来。1. 在数据层面只维护一张包含所有指标的MySQL表,表中的stday字段作为索引,stday=当天的保存实时数据,stday<当天的保存离线数据。典型的大数据架构,除了Lambda架构之外,还有kappa架构,这两个架构的区别如下标所示,请补充表中空(1)-(4)第二,实时数据只对接了内部的kafka消息,没有实时的获取第三方的曝光、点击、浏览数据。

qq837993702的博客 66

【Linux 网络编程 】

【Linux 网络编程 】

aoeaoao的博客 1348

OTA 升级失败/回滚策略设计:打造安全可靠的双分区/断点续传/签名校验方案

双分区机制(A/B Partitioning)是OTA升级的“保险箱”。简单来说,设备存储分为两个分区:A分区(当前运行)和B分区(备用)。升级时,新固件写入B分区,A分区保持不变。如果升级成功,系统切换到B分区运行;如果失败,设备直接回滚到A分区,完全不受影响。这就像玩游戏存档:你打Boss前存了个档,万一挂了还能读档重来。双分区就是设备的“读档”机制,避免了变砖的尴尬。以Android设备为例,Google从Android 7.0开始强制引入A/B分区机制(Seamless Updates)。

大模型大数据攻城狮的专栏 1230

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

嵌入式Linux网络编程:UNIX Domain Socket进程间通信(IPC)

通过本文,您可掌握UNIX Domain Socket在嵌入式Linux中的高效IPC实现方法。相比网络套接字,UDS在本地通信场景中性能更优、资源占用更少,非常适用于嵌入式设备的多模块协作!

m0_64657422的博客 1207

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

转载的几篇网络编程的好文章

http://blog.chinaunix.net/uid-23069658-id-3271110.html

kankan231的专栏 740

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【Linux网络编程】02---网络编程套接字---socket编程常用接口

🍁你好,我是📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识。

RO-BERRY 1571

【Linux网络】Linux网络编程套接字,UDP与TCP

在当今这个信息技术日新月异的时代,网络编程已成为连接世界、构建各类互联网应用不可或缺的一部分。而Linux,作为开源操作系统的典范,其强大的网络功能和灵活性,为开发者们提供了一个广阔而深入的实践平台。在众多网络编程技术中,套接字(Socket)编程无疑是核心与基石,它不仅支撑着Web服务、即时通讯、在线游戏等日常应用,还是实现分布式系统、云计算服务的关键技术之一。

EterNity_TiMe_的计算机学习之路 5619

Linux 网络编程从入门到进阶 学习指南

大家好,我是小康。在上一篇文章中,我们探讨了 Linux 系统编程的诸多基础构件,包括文件操作、进程管理和线程同步等,接下来,我们将视野扩展到网络世界。在这个新篇章里,我们要让应用跳出单机限制,学会在网络上跨机器交流信息。 接下来,我们要深入套接字(sockets)和 TCP/IP 协议,揭示如何在 Linux 下构建通信和网络服务。我们会从基础说起,逐步深入。目标是为初学者提供一个 Linux 网络编程从入门到进阶的学习指南! 网络通信基础 思考一下,如果计算机想要“交朋友”,它们需要怎样互相沟通?

Henry313的博客 1123

Linux C编程之十六 网络编程基础-socket

Linux C编程之十六 网络编程基础-socket - pointerC++ - 博客园 (cnblogs.com)

唐攀的博客 334

技术演进中的开发沉思-100 Linux服务编程系列: 网络编程基础 API (上)

本文详细介绍了Linux网络编程中的核心API及其使用流程。主要内容包括:1. socket地址处理:涵盖字节序转换(htonl/htons等)、通用与专用地址结构(sockaddr/sockaddr_in)、IP地址转换函数(inet_aton/ntoa)等基础概念;2. socket操作:创建socket的流程及参数解析,包括域、类型和协议的选择;3. 连接管理:服务器端的bind()、listen()、accept()调用流程,客户端的connect()实现,以及错误处理方法。文章通过类比和代码示例,

你的天空阅读专栏 848

Linux Socket编程

应用层的下一层是传输层,所以 socket 编程需要我们了解 UDP 和 TCP 的区别和作用。其他层的协议,并不在应用层上不会进行操作。在进行网络连接时,我们会在 UDP 和 TCP 两种连接方式中进行选择。

laimaxgg 1057

Linux系统编程——socket套接字网络编程

TCP / UDP 对比 1、TCP 面向连接(如打电话要先拨号建立连接);UDP 是无连接的,即发送数据之前不需要建立连接 2、TCP 提供可靠的服务,也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付 3、TCP 面向字节流,实际上是 TCP 把数据看成一连串无结构的字节流;UDP 是面向报文的,UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等) 4、每一条 TCP 连接只

莘莘的博客 980

《Linux高性能服务器编程》学习笔记——第五章 Linux网络编程基础API(2)

现在学习Linux网络编程基础API第二个部分,socket编程的基础操作API。 二、socket基础API 1、创建socket linux中一切皆文件,socket是可读可写可控制可关闭的文件描述符。创建socket的系统调用: #include #include int socket(int domain, int type, int protocol); d

爱很遥远 469
上一篇: Linux_C++网络编程四种CS模型
下一篇: Makefile进阶案例_高手专用
Howrun777
博客等级 码龄1年 133粉丝 100原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值