linux C语言socket函数recv

recv 函数是在 Linux C 语言网络编程中用于从已连接的套接字接收数据的函数。它通常与 TCP 连接一起使用,但也可以用于 UDP(尽管对于 UDP,更常使用 recvfrom,因为它还可以接收发送方的地址信息)。

函数原型

recv 函数在 <sys/socket.h> 中定义,其函数原型如下:

#include <sys/types.h>
#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数

  1. sockfd
    这是一个已打开的套接字描述符,它标识了要从其接收数据的网络连接。对于 TCP,这个套接字通常是通过 socket 函数创建的,并且已经通过 connect 函数与远程服务器建立了连接,或者通过 accept 函数接受了来自客户端的连接。

  2. buf
    这是一个指向缓冲区的指针,该缓冲区用于存储从套接字接收到的数据。在调用 recv 函数之前,应确保该缓冲区有足够的空间来存储要接收的数据。

  3. len
    这是缓冲区 buf 的长度,以字节为单位。它指定了缓冲区中可以存储的最大数据量。

  4. flags
    这是一个整数值,用于传递特殊的接收标志给底层协议。这些标志可以修改 recv 函数的行为。通常,这个参数被设置为 0,表示使用标准的接收行为。然而,一些可能的标志包括:

    • MSG_PEEK:查看数据,但不从套接字的接收队列中移除。
    • MSG_WAITALL:等待直到接收到完整的 len 字节数据,或者发生错误。然而,这个标志的行为可能因实现而异,并且不建议在阻塞模式下使用。
    • MSG_OOB:仅接收带外数据(out-of-band data)。
    • MSG_DONTWAIT:非阻塞模式操作(等效于使用非阻塞套接字)。
    • MSG_ERRQUEUE:获取扩展的错误信息(较少使用)。

返回值

  • 如果成功,recv 函数返回实际接收到的字节数。这个数字可能小于 len 参数指定的长度,这取决于发送方发送的数据量、套接字的接收缓冲区中的数据量以及网络条件。
  • 如果连接已正常关闭,recv 函数返回 0。
  • 如果出现错误,recv 函数返回 -1,并设置全局变量 errno 以指示错误类型。

错误处理

当 recv 函数返回 -1 时,可以检查 errno 来确定错误的原因。一些常见的错误包括:

  • EWOULDBLOCK 或 EAGAIN:套接字是非阻塞的,并且没有数据可供立即接收。
  • ECONNRESET:连接被对端重置。
  • ENOTCONN:套接字未连接到远程地址。
  • EINTR:接收操作被中断,通常是因为接收到了一个信号。
  • EBADF:提供的套接字描述符不是有效的或不支持接收操作。

注意事项

  1. 阻塞与非阻塞:根据套接字的配置,recv 函数可以表现为阻塞或非阻塞。在阻塞模式下,recv 会等待直到有数据可以接收或发生错误。在非阻塞模式下,如果没有数据可供接收,recv 会立即返回 EWOULDBLOCK 或 EAGAIN 错误。

  2. 多次接收:由于 TCP 的流性质,一次 recv 调用可能不会接收到发送方发送的所有数据。因此,可能需要多次调用 recv 来接收完整的消息或数据流。

  3. 数据边界recv 函数不保证按发送方发送的原始边界接收数据。应用程序需要自己处理消息的边界问题,通常通过在消息前加上长度字段或使用特定的分隔符。

  4. 关闭连接:当对端关闭连接时,recv 函数将返回 0,表示没有更多的数据可以接收。这是正常关闭连接的指示。

  5. 性能考虑:与 send 类似,频繁地接收小块数据可能不如一次性接收大块数据高效。应用程序应优化数据传输以提高性能。

在使用 recv 函数时,应处理可能的错误和异常情况,并确保正确地管理套接字和数据缓冲区。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>int main() {// 假定 sockfd 是已经连接好的套接字int sockfd = /* socket(...) */;// 用于存储接收数据的缓冲区char buffer[1024];// 清空缓冲区memset(buffer, 0, sizeof(buffer));// 接收数据int bytes_received = recv(sockfd, buffer, sizeof(buffer), 0);if (bytes_received < 0) {// 处理错误perror("recv failed");} else if (bytes_received == 0) {// 对方已经关闭了连接printf("Peer has performed an orderly shutdown\n");} else {// 打印接收到的数据printf("Received (%d bytes): %.*s\n", bytes_received, bytes_received, buffer);}// 关闭套接字close(sockfd);return 0;
}

在上面的代码示例中,`sockfd` 应已经是一个成功连接的 socket—这意味着在 TCP 的情况下,应该在客户端使用 connect 或在服务器端使用 accept 来获得 sockfd

在实际应用程序中,通常会将 recv 放在某个循环中以持续接收数据。当 recv 返回 0 表示对方已经关闭了连接,接收循环就应该结束。还需要处理各种可能出现的错误。

perror 函数是 C 语言中用来报告 errno 错误的常用方法。当系统调用或库函数出错时,它们通常会设置全局变量 errno 来指示错误的类型。perror 函数可以读取当前的 errno 值,并打印出一条描述该错误的消息到标准错误输出(stderr)。

perror 函数的原型如下:

void perror(const char *str);

其中 str 是一个字符串指针,它通常被用来提供关于出错上下文的额外信息。这个字符串会被打印出来,后面紧跟着一个冒号、一个空格和由 errno 值对应的错误消息。

例如,如果你调用了一个可能失败的函数(如 open),你可以立即调用 perror 来打印出任何发生的错误:

	#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> int main() { int fd = open("nonexistent_file.txt", O_RDONLY); if (fd == -1) { perror("Error opening file"); return EXIT_FAILURE; } // ... 其他代码 ... return EXIT_SUCCESS; }

如果文件 nonexistent_file.txt 不存在,open 函数会失败,并设置 errno。然后 perror 会打印出类似以下的消息:

Error opening file: No such file or directory

这里,“Error opening file” 是传递给 perror 的字符串,而 “No such file or directory” 是与 errno 值对应的系统错误消息。注意,errno 的值在调用另一个可能设置 errno 的函数之前应当被认为是未定义的,除非你明确地知道它不会被改变。因此,通常在调用可能出错的函数之后立即检查 errno 并使用 perror 或其他方法来报告错误是一个好习惯。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/634929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC基础知识学习笔记

Universe Infinity Inc. 目录 一、学习SpringMVC主要是学什么1、SpringMVC的基本原理2、SpringMVC学习串联 二、快速体验SpringMVC的开发1、新建项目&#xff0c;转成web项目2、引入依赖3、编写Spring的配置类4、配置web启动类&#xff0c;替代web.xml5、编写Handler&#xff…

第十二篇【传奇开心果系列】Ant Design Mobile of React开发移动应用:内置组件实现酷炫CSS 动画

Ant Design Mobile of React 开发移动应用示例博文系列 第一篇【传奇开心果系列】Ant Design Mobile of React 开发移动应用:从helloworld开始 第二篇【传奇开心果系列】Ant Design Mobile of React 开发移动应用:天气应用 第三篇【传奇开心果系列】Ant Design Mobile of Reac…

beego的模块篇 - I18n国际化

1. i18n 安装导入 安装该模块&#xff1a; go get github.com/beego/i18n 导入引用包&#xff1a; import ("github.com/beego/i18n" ) conf 目录下就有 locale_en-US.ini 和 locale_zh-CN.ini 两个本地化文件。 本地化文件的文件名和后缀是随意的&#xff0c;不…

MySQL 索引(上)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL-进阶篇 &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现…

libpcap简明教程

文章目录 前言tcpdump的使用libpcap API的简单使用libpcap API的进阶使用 前言 因为之前简单写过wireshark入门指北&#xff0c;所以我知道基本的抓包流程。最近尝试调用libpcap的C API接口&#xff0c;顺道整理下。 本文实验如下&#xff1a; 使用tcpdump命令抓取目标地址为…

【漏洞复现】Hikvision SPON IP网络对讲广播系统命令执行漏洞(CVE-2023-6895)

文章目录 前言声明一、系统简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 Hikvision Intercom Broadcasting System是中国海康威视&#xff08;Hikvision&#xff09;公司的一个对讲广播系统。 声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播…

[已解决]前端使用el-upload,后端使用文件上传阿里云报错:异常信息:java.lang.NullPointerException: null

前端使用el-upload&#xff0c;后端使用文件上传阿里云报错&#xff1a; 报错原因&#xff1a;前端image参数未传进去 解决方法&#xff1a;在el-upload添加属性 name"image" 文件传进去了&#xff01;

回溯法:0-1背包问题

问题描述 给定种物品和一背包。 物品的重量是&#xff0c; 其价值为&#xff0c;背包的容量为 c。 问应该如何选择装入背包中的物品&#xff0c;使得装入背包中物品的总价值最大&#xff1f;注意物品不重复! 实例&#xff1a;物品价值V{12, 11, 9, 8}, 物品重量W{8, 6, 4, 3},…

手写Vue3源码

Vue3核心源码 B站视频地址&#xff1a;https://www.bilibili.com/video/BV1nW4y147Pd?p2&vd_source36bacfbaa95ea7a433650dab3f7fa0ae Monorepo介绍 Monorepo 是管理项目代码的一种方式&#xff0c;只在一个仓库中管理多个模块/包 一个仓库可以维护多个模块&#xff0c;…

Fog-Aware Adaptive YOLO for Object Detection in Adverse Weather

Abstract 提出了一种雾自适应YOLO算法。使用一种雾评估算法将图片分为有雾和无雾图片&#xff0c;随后将标准的YOLO应用于正常图片&#xff0c;自适应YOLO应用于有雾图片。 Method 目前的除雾方法去除雾霾时不考虑其雾度和发生频率。例如&#xff0c;图像自适应YOLO算法[6]试…

【已解决】Qt Creator设计模式被禁用不能点的原因及解决方案

Qt Creator 下载地址&#xff08;含历史版本&#xff09;&#xff1a;https://download.qt.io/official_releases/qtcreator/ 症状 Qt Creator 目前最新版为12.0.1&#xff0c;安装后打开.qml文件发现设计工具图标为禁用状态。 原因及解决方案 根据官网材料&#xff08;Qt C…

机器视觉检测设备在连接器外观缺陷检测中的应用

作为传输电流或信号连接两个有源器件的器件&#xff0c;连接器被广泛应用于各个行业&#xff0c;从手机、平板、电脑&#xff0c;到冰箱、空调、洗衣机&#xff0c;再到汽车、国防、航空&#xff0c;处处是它的所在。每个电子产品少了连接器将无法运作&#xff0c;因此&#xf…

Python——面向对象案列

1. class User(object):#重写__int__初始化方法&#xff0c;该方法用来初始化属&#xff0c;在构建方法的时候&#xff0c;这个方法会自动触发&#xff0c;用来初始化属性def __init__(self): #name “” 这是一个局部变量#self类似指针 this#self.name类的属性print("构…

计算机网络-甘晴void学习笔记

计算机网络 计科210X 甘晴void 202108010XXX 文章目录 计算机网络期中复习1计算机网络和因特网1.1 因特网1.2 网络边缘1.3 网络核心1.4 分组交换的时延/丢包和吞吐量1.5 协议层次与服务模型 2 应用层原理2.1 应用层协议原理2.2 Web和Http2.3 因特网中的电子邮件2.4 DNS&#x…

K8S--部署Nacos

原文网址&#xff1a;K8S--部署Nacos-CSDN博客 简介 本文介绍K8S部署Nacos的方法。Nacos版本是&#xff1a;2.2.3。 部署方案 本文为了简单&#xff0c;使用此部署方式&#xff1a;使用本地pvconfigmap&#xff0c;以embedded模式部署单机nacos。以nodePort方式暴露端口。 …

vectorCast——Probe point 功能实现故障注入,局部变量打印,断点调试。

选择一个测试用例,选择coverage窗口进行查看。点击edit probe point,如图所示绿色的小圆圈。选代码中选择需要打断点的地方进行点击。黑色的小圆点都可以选。点击黑色小圆点,小圆点变绿,表示打断点成功。此时就可以根据自己的需求在打断点的位置编写一些C语言的命令语句。点…

线程同步--生产者消费者模型--单例模式线程池

文章目录 一.条件变量pthread线程库提供的条件变量操作 二.生产者消费者模型生产者消费者模型的高效性基于环形队列实现生产者消费者模型中的数据容器基于生产者消费者模型实现单例线程池 一.条件变量 条件变量是线程间共享的全局变量,线程间可以通过条件变量进行同步控制条件…

ffmpeg 常用命令行详解

概述 ffmpeg 是一个命令行音视频后期处理软件 1. 裁剪命令 参数说明 -i 文件&#xff0c;orgin.mp3 为待处理源文件-ss 裁剪时间&#xff0c;后跟裁剪开始时间&#xff0c;或者开始的秒数-t 裁剪时间output.mp3 为处理结果文件 ffmpeg -i organ.mp3 -ss 00:00:xx -t 120 o…

无刷电机学习-原理篇

一、无刷电机的优点 使用一项东西首先就要明白为什么要使用它&#xff0c;使用它有什么优点。与有刷电机相比无刷电机除了控制繁琐几乎全是优点。 1、应用范围广&#xff1a;家用电器&#xff08;冰箱空调压缩机、洗衣机、水泵等&#xff09;、汽车、航空航天、消费品工业自动…

4个值得使用的免费爬虫工具

在信息时代&#xff0c;数据的获取对于各行业都至关重要。而在数据采集的众多工具中&#xff0c;免费的爬虫软件成为许多用户的首选。本文将专心分享四款免费爬虫工具&#xff0c;突出介绍其中之一——147采集软件&#xff0c;为您揭示这些工具的优势和应用&#xff0c;助您在数…