linux C语言socket函数send
在Linux中,使用C语言进行网络编程时,send函数是用于发送数据到已连接的套接字的重要函数
之一。它通常用于TCP连接,但也可以用于UDP(尽管对于UDP,通常更推荐使用sendto,因为它允许你指定目标地址和端口)。
下面是send函数的详细解释:
函数原型
recv 函数在 <sys/socket.h> 中定义,其函数原型如下:
#include <sys/types.h>
#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数
-
sockfd:
这是一个已打开的套接字描述符,它标识了要通过其发送数据的网络连接。对于TCP,这个套接字通常是通过socket函数创建的,并且已经通过connect函数与远程服务器建立了连接。 -
buf:
这是一个指向要发送数据的缓冲区的指针。这个缓冲区包含了要通过网络发送的字节流。缓冲区中的数据在调用send函数时并不会被自动修改。 -
len:
这是要发送数据的长度,以字节为单位。它指定了buf指针指向的缓冲区中有效数据的量。 -
flags:
这是一个整数值,用于传递特殊的发送标志给底层协议。这些标志可以修改send函数的行为。通常,这个参数被设置为0,表示使用标准的发送行为。然而,一些可能的标志包括:MSG_OOB:发送带外数据(out-of-band data),这是一种紧急数据,通常用于TCP连接。MSG_DONTROUTE:绕过标准的路由表查找,通常用于本地通信。MSG_NOSIGNAL:请求不发送SIGPIPE信号,如果接收端已经关闭了连接,则send函数将返回错误而不是终止进程。
返回值
- 如果成功,
send函数返回实际发送的字节数。这个数字可能小于len参数指定的长度,这取决于套接字的发送缓冲区可用空间和网络条件。 - 如果出现错误,
send函数返回-1,并设置全局变量errno以指示错误类型。
错误处理
当send函数返回-1时,可以检查errno来确定错误的原因。一些常见的错误包括:
EWOULDBLOCK或EAGAIN:套接字是非阻塞的,并且没有足够的缓冲区空间可供立即发送数据。ECONNRESET:连接被对端重置。EPIPE:对端关闭了连接,并且启用了SIGPIPE信号(除非设置了MSG_NOSIGNAL标志)。EBADF:提供的套接字描述符不是有效的或不支持发送操作。EINTR:发送操作被中断,通常是因为接收到了一个信号。
注意事项
-
阻塞与非阻塞:根据套接字的配置,
send函数可以表现为阻塞或非阻塞。在阻塞模式下,send会等待直到有足够的缓冲区空间可以发送数据或发生错误。在非阻塞模式下,如果没有足够的缓冲区空间,send会立即返回EWOULDBLOCK或EAGAIN错误。 -
多次发送:即使
send的返回值小于请求的len,也不意味着发送失败。在TCP中,由于流量控制和窗口大小,可能需要多次调用send来发送所有数据。 -
数据完整性:
send函数不保证数据的原子性。如果需要在两个进程或两台机器之间原子性地发送数据,通常需要在应用层实现额外的协议。 -
关闭连接:当对端关闭连接时,继续向其发送数据可能会导致
EPIPE错误(如果未设置MSG_NOSIGNAL标志)或SIGPIPE信号。 -
性能考虑:频繁地发送小块数据可能不如一次性发送大块数据高效,因为网络传输和操作系统调用都有一定的开销。
在使用send函数时,务必考虑上述因素,并适当地处理可能的错误和异常情况。
示例代码
#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库函数,用于打印一个描述性的错误消息到标准错误输出 stderr。它会根据全局变量 errno 的当前值来显示当前错误的文本描述。
errno 是在发生系统调用或库函数调用出错时设置的全局变量,它的值表示错误的类型。<errno.h> 头文件定义了errno 可能的错误代码(例如 EACCES、ECONNRESET 等)和对应的错误信息。
perror 的原型定义如下:
#include <stdio.h>
void perror(const char *s);
当你调用 perror 时,你可以提供一个字符串作为参数,perror会先打印这个字符串,后接一个冒号和一个空格,然后是对应 errno 值的字符串描述。最后,它会添加一个换行符。
例如:
if (write(fd, buf, count) == -1) {perror("write failed");// 这里还可以包含额外的错误处理代码
}
如果 write 调用失败,你将看到像 "write failed: Permission denied" 这样的错误消息被打印到标准错误输出。
如果 errno 值是0,表示没有发生错误,perror函数通常不会打印有关错误的信息。
为了确保 perror显示的是你关心的错误信息,最好在调用可能设置errno的函数之后立即使用perror— 在任何其他可能再次设置 errno 的操作之前。这是因为许多函数都可能更改 errno 值,包括成功的函数调用。通常,在检查函数调用返回值时,如果发现它出错(通常返回值是 -1 或者 NULL),马上用 perror 来查看错误原因。
相关文章:
linux C语言socket函数send
在Linux中,使用C语言进行网络编程时,send函数是用于发送数据到已连接的套接字的重要函数之一。它通常用于TCP连接,但也可以用于UDP(尽管对于UDP,通常更推荐使用sendto,因为它允许你指定目标地址和端口&…...
Django(八)
1. 管理员操作 1.1 添加 from django.shortcuts import render, redirectfrom app01 import models from app01.utils.pagination import Paginationfrom django import forms from django.core.exceptions import ValidationError from app01.utils.bootstrap import BootStr…...
上海计算机学会12月月赛 丙组题解
上海计算机学会 12 月月赛 丙组题解涉及知识点:数学、字符串、模拟、裴蜀定理、宽度优先搜索、动态规划 比赛链接:https://iai.sh.cn/contest/58 第一题:T1数砖数 标签:数学题意:给定一种 2 2 2x 2 2 2的瓷砖&#…...
nextjs中beforePopState使用
在某些情况下,希望监听popstate并在路由器对其进行操作之前执行某些操作。可以使用beforePopState。 在Next.js中,beforePopState是一个可选的生命周期函数,用于在浏览器的历史记录发生更改之前执行一些操作。具体来说,beforePopS…...
【并发编程】活锁
📝个人主页:五敷有你 🔥系列专栏:并发编程 ⛺️稳重求进,晒太阳 活锁 定义:活锁出现在两个线程互相改变对象的结束条件,最后谁也无法结束 代码示例 public class TestLiveLock {stati…...
CSMM和CMMI之间有什么区别?
CSMM(软件能力成熟度评估)和CMMI(能力成熟度模型集成)都是软件行业中用于评估和提高企业软件开发过程成熟度的模型。它们之间的主要区别在于起源、定位、适应范围和具体内容。 1. 起源与定位: - CMMI是由美国卡耐基…...
企业面临的典型网络安全风险及其防范策略
网络安全威胁是一种技术风险,会削弱企业网络的防御能力,危及专有数据、关键应用程序和整个IT基础设施。由于企业面临着广泛的威胁,因此通过监控和缓解最关键的威胁和漏洞。网络安全问题有七大类,包括多种威胁,以及团队…...
JavaScript进阶:WebAPIs重点知识整理1
目录 1 DOM修改元素内容 2 DOM修改元素常见属性 3 修改元素样式属性 3.1 通过style修改元素样式 3.2 通过类名className修改元素样式 3.3 通过classList修改元素样式 4 操作表单元素属性 5 自定义属性 6 定时器 7 事件监听 7.1 点击事件 click 7.2 鼠mouseenter和移…...
【Nginx】使用自生成证书配置nginx代理https
使用Nginx代理HTTPS请求并使用自签名证书,可以按照以下步骤进行配置: 生成自签名证书: 打开终端或命令提示符,并导航到Nginx配置文件所在的目录。运行以下命令生成自签名证书和私钥: openssl req -x509 -nodes -days 3…...
【Linux】文件周边001之系统文件IO
👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.C语言文件IO 1.1…...
防火墙接口配置实验
1、搭建拓扑 2、给云端添加网络,来实现真机与虚拟机的连接 3、 给防火墙g0/0/0口配置IP,由于我云端绑定的是192.168.100.10,所以这里IP配置为192.168.100.1/24,使用命令开启防火墙远程连接的服务,之后便可通过web远程登陆防火墙 …...
《WebKit 技术内幕》学习之五(4): HTML解释器和DOM 模型
4 影子(Shadow)DOM 影子 DOM 是一个新东西,主要解决了一个文档中可能需要大量交互的多个 DOM 树建立和维护各自的功能边界的问题。 4.1 什么是影子 DOM 当开发这样一个用户界面的控件——这个控件可能由一些 HTML 的标签元素…...
SpringBoot+Vue充电桩管理系统 附带详细运行指导视频
文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1. 分页获取预约数据代码2.保存预约信息代码3.修改订单状态代码 一、项目演示 项目演示地址: 视频地址 二、项目介绍 项目描述:这是一个基于SpringBootVue框架开发的充电桩管理系统。首先&…...
【数据结构】二叉树算法讲解(定义+算法原理+源码)
博主介绍:✌全网粉丝喜爱、前后端领域优质创作者、本质互联网精神、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战✌有需要可以联系作者我哦! 🍅附上相关C语言版源码讲解🍅 ὄ…...
Vue3基础:挂载事例方法.mount()是什么?根组件模板又是什么?
.mount() <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Vue 3 演示</title> </head>…...
Unity 面试篇|(七)Unity渲染与Shader篇 【全面总结 | 持续更新】
目录 1.问一个Terrain,分别贴3张,4张,5张地表贴图,渲染速度有什么区别?为什么?2.什么是LightMap?3.MipMap是什么,作用?4.请问alpha test在何时使用?能达到什么…...
记录一些多维数组的方法
文章目录 前言一、获取多维数组的数据二、多维数组自带的方法总结 前言 验证过程中,我们经常会用到多维数组存储数据,本文主要记录一下,如何去获取我们需要的数据,以及多维数组自带的一些方法。 一、获取多维数组的数据 获取多维…...
Linux:gcc的相关知识
目录 gcc的翻译(编译)过程: 预处理: 条件编译: 编译: 汇编&链接: 什么是链接? 安装静态库: 静态库的使用: 动态静态的对比: 优缺对比…...
Linux的奇妙冒险———vim的用法和本地配置
vim的用法和本地配置 一.vim的组成和功能。1.什么是vim2.vim的多种模式 二.文本编辑(普通模式)的快捷使用1.快速复制,粘贴,剪切。2.撤销,返回上一步操作3.光标的控制4.文本快捷变换5.批量化操作和注释 三.底行模式四.v…...
微信小程序底部按钮适配iPhoneX以上,显示遮挡问题
只需要在给底部按钮加个样式 /* 底部导航栏容器 */ .button-box {/* 使用 safe-area-inset-bottom 属性适配 iPhone X 及以上型号设备 */padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom);/* 其他样式属性 */ }iPhone6/7/8效果 …...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
