Linux中的read/write和recv/send的区别,并使用recv/send实现简单的聊天功能

85 篇文章 8 订阅
订阅专栏

r e a d / w r i t e read/write read/write的用法

在 Linux 中,read() 和 write() 是用于在文件描述符上进行数据读写的函数。它们的用法如下:

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

ssize_t write(int fd, const void *buf, size_t count);

其中, f d fd fd 是一个已经打开的文件描述符;
b u f buf buf 是一个指向读或写数据的缓冲区指针;
c o u n t count count 是缓冲区的长度。

r e a d ( ) read() read() 函数用于从文件描述符中读取数据,它会阻塞程序直到读取到数据或发生错误。它返回读取到的字节数,如果返回值为 0 0 0,则表示已经到达文件末尾。如果返回值为 − 1 -1 1,则表示出现了错误,可以通过 e r r n o errno errno 变量来获取错误码。

w r i t e ( ) write() write() 函数用于向文件描述符中写入数据,它会阻塞程序直到所有数据都被写入完毕或发生错误。它返回写入的字节数,如果返回值小于指定的长度,则表示出现了错误。可以通过 e r r n o errno errno 变量来获取错误码。

需要注意的是, r e a d ( ) read() read() w r i t e ( ) write() write() 是基于字节流的,它们不会保留消息的边界信息。如果需要保留消息的边界信息,可以使用 r e a d ( ) read() read() w r i t e ( ) write() write() 函数。

r e c v / s e n d recv/send recv/send的用法

L i n u x Linux Linux 中, r e c v ( ) 和 s e n d ( ) recv() 和 send() recv()send() 是用于在网络套接字上进行数据收发的函数。它们的用法如下:

#include <sys/socket.h>

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

其中, s o c k f d sockfd sockfd 是一个已经创建好的、打开的套接字文件描述符;
b u f buf buf 是一个指向接收或发送数据的缓冲区指针;
l e n len len 是缓冲区的长度;
f l a g s flags flags 是一组标志参数,它们控制着函数的行为。

r e c v ( ) recv() recv() 函数用于从套接字中接收数据,它会阻塞程序直到接收到数据或发生错误。它返回接收到的字节数,如果返回值为 0 0 0,则表示连接已经关闭。如果返回值为 − 1 -1 1,则表示出现了错误,可以通过 e r r n o errno errno 变量来获取错误码。 r e c v ( ) recv() recv() 函数的常用标志参数有:

  • MSG_WAITALL:阻塞等待直到接收到指定长度的数据。
  • MSG_PEEK:接收数据但不从接收缓冲区中删除数据。
  • MSG_OOB:接收带外数据。

s e n d ( ) send() send() 函数用于向套接字中发送数据,它会阻塞程序直到所有数据都被发送完毕或发生错误。它返回发送的字节数,如果返回值小于指定的长度,则表示出现了错误。可以通过 e r r n o errno errno 变量来获取错误码。 s e n d ( ) send() send() 函数的常用标志参数有:

  • MSG_DONTWAIT:非阻塞发送数据。
  • MSG_MORE:告诉内核还有更多数据需要发送。
  • MSG_NOSIGNAL:在发送数据时忽略 SIGPIPE 信号。

L i n u x Linux Linux中的 r e a d / w r i t e read/write read/write r e c v / s e n d recv/send recv/send的区别

L i n u x Linux Linux中, r e a d / w r i t e read/write read/write r e c v / s e n d recv/send recv/send是用于从 文件描述符 文件描述符 文件描述符 套接字 套接字 套接字进行数据读写的系统调用。它们之间的主要区别如下:

  1. 参数不同
    r e a d / w r i t e read/write read/write的参数是 文件描述符、缓冲区和读 / 写字节数 文件描述符、缓冲区和读/写字节数 文件描述符、缓冲区和读/写字节数
    r e c v / s e n d recv/send recv/send的参数是 套接字、缓冲区和读 / 写字节数 套接字、缓冲区和读/写字节数 套接字、缓冲区和读/写字节数

  2. 返回值不同
    r e a d / w r i t e read/write read/write的返回值为已读/写字节数,如果遇到错误则返回-1。
    r e c v / s e n d recv/send recv/send的返回值为已接收/发送字节数,如果遇到错误则返回-1。

  3. 应用场景不同
    r e a d / w r i t e read/write read/write通常用于 读写普通的文件、管道等 读写普通的文件、管道等 读写普通的文件、管道等
    r e c v / s e n d recv/send recv/send则用于 网络编程中的套接字通信 网络编程中的套接字通信 网络编程中的套接字通信

  4. 处理方式不同
    r e a d / w r i t e read/write read/write在读写时使用文件偏移量来确定从哪里读取或写入数据,并根据需要更新该偏移量。
    r e c v / s e n d recv/send recv/send则没有类似的偏移量概念,它们一次性读取或发送指定数量的数据。

总体而言, r e a d / w r i t e read/write read/write适合用于本地文件和管道等,而 r e c v / s e n d recv/send recv/send适合用于网络通信中的套接字。

下面是一个使用read/write进行文件读写操作的例子:

该程序打开一个名为 t e s t . t x t test.txt test.txt的文件,并使用 r e a d read read将其内容读取到缓冲区中,然后使用 w r i t e write write将内容写入标准输出。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

int main() {
    int fd = open("test.txt", O_RDWR);
    if (fd == -1) {
        printf("Failed to open file\n");
        exit(1);
    }
    
    char buffer[1024];
    int num_read = read(fd, buffer, sizeof(buffer));
    if (num_read == -1) {
        printf("Failed to read file\n");
        exit(1);
    }
    
    int num_written = write(STDOUT_FILENO, buffer, num_read);
    if (num_written == -1) {
        printf("Failed to write file\n");
        exit(1);
    }

    close(fd);
    return 0;
}

下面是一个使用recv/send进行网络通信的例子:

下面是一个使用recv/send进行网络通信的服务器与客户端互发消息的例子:

// Server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define PORT 8081

int main()
{
    int server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock == -1)
    {
        printf("Failed to create socket\n");
        exit(1);
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
    {
        printf("Failed to bind\n");
        exit(1);
    }

    if (listen(server_sock, 5) == -1)
    {
        printf("Failed to listen\n");
        exit(1);
    }

    printf("Server is listening on port %d...\n", PORT);

    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    int client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_addr_len);
    if (client_sock == -1)
    {
        printf("Failed to accept connection\n");
        exit(1);
    }

    char buffer[1024];
    while (1)
    {

        memset(buffer, 0, sizeof buffer);                                // 收之前先把缓存区清空
        int num_received = recv(client_sock, buffer, sizeof(buffer), 0); /收///
        if (num_received == -1)
        {
            printf("Failed to receive message\n");
            exit(1);
        }
        else if (num_received == 0)
        {
            break; // Client closed connection
        }

        printf("Received message: %s", buffer);

        const char *message = "Hello, client!\n";
        int num_sent = send(client_sock, message, strlen(message), 0); ///发
        if (num_sent == -1)
        {
            printf("Failed to send message\n");
            exit(1);
        }
    }

    close(client_sock);
    close(server_sock);
    return 0;
}

该程序创建了一个服务器套接字,绑定到指定端口,并使用listen开始监听。当客户端连接时,使用accept接受连接并进行通信。在接受到客户端发送的消息后,服务器会将其打印出来,并向客户端发送一条回复。

// Client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define PORT 8081

int main()
{
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1)
    {
        printf("Failed to create socket\n");
        exit(1);
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
    {
        printf("Failed to connect\n");
        exit(1);
    }

    char buffer[1024];
    while (1)
    {
        printf("Enter message: ");
        fgets(buffer, sizeof(buffer), stdin);

        int num_sent = send(sock, buffer, strlen(buffer), 0); /发/
        if (num_sent == -1)
        {
            printf("Failed to send message\n");
            exit(1);
        }
        else if (num_sent == 0)
        {
            break; // Server closed connection
        }

        memset(buffer, 0, sizeof buffer);                         // 收之前先把缓存区清空
        int num_received = recv(sock, buffer, sizeof(buffer), 0); /收//
        if (num_received == -1)
        {
            printf("Failed to receive message\n");
            exit(1);
        }
        else if (num_received == 0)
        {
            break; // Server closed connection
        }

        printf("Received message: %s", buffer);
    }

    close(sock);
    return 0;
}

该程序创建了一个客户端套接字,连接到服务器。在输入一条消息后,使用send向服务器发送该消息,并收到服务器的回复。当检测到服务器关闭连接时,程序退出。

这两个程序可以相互通信,实现简单的聊天功能。
在这里插入图片描述

linux socketrecvrecvfrom、readrecvmsg、readv比较
数字人生
06-27 2336
函数原型:`ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);- 特点:`recvfrom`和`recv`的主要区别在于`recvfrom`可以接收发送方的地址信息,因此非常适合用于无连接的UDP通信。- 特点:相对于`recv`和`recvfrom`,`read`没有`flags`参数,只进行普通的数据读取操作。
【socket】recvfrom/sendto、recv/sendread/write问答
数字人生
08-14 1171
【代码】【socket】recvfrom/sendto、recv/sendread/write问答。
readrecv区别
m0_46376834的博客
07-13 1053
【代码】readrecv区别
linux sendrecv函数详解
weixin_30376453的博客
08-30 1162
1 #include <sys/socket.h> 2 ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); 3 ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags); recvsend的前3个参数等同于read...
Linux Socket---write/send/sendto/wirev/sendmsg
迷失的专栏
10-18 1503
首先,我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程涉及到的相关数据结构;在我们的虚拟机上发送icmp回显请求包,ping另一台主机192.168.1.111。我们使用系统调用sendto发送这个icmp包。 ssize_t sendto(int s, const void *buf, size_t len, int flags, ...
linux下的socket的read,socket网络编程readrecv区别
weixin_35148673的博客
05-15 1519
1、readrecv 区别read 原则:数据在不超过指定的长度的时候有多少读多少,没有数据则会一直等待。所以一般情况下:我们读取数据都需要采用循环读的方式读取数据,因为一次read 完毕不能保证读到我们需要长度的数据,read 完一次需要判断读到的数据长度再决定是否还需要再次读取。recv 原则:recv 有一个MSG_WAITALL 的参数:recv(sockfd, buff, buf...
linux recv\readsend/write区别
往哪儿
03-12 553
recv/sendread/write功能都差不多,只是recv/send提供了第四个参数来控制读写操作. int recv(int sockfd,void *buf,int len,int flags) int send(int sockfd,void *buf,int len,int flags) flags可以是0与以下参数异或,如果flags为0,则和read,
write/readrecv/sendrecvfrom/sendto,,recvmsg/sendmsg的区别
粉丝头子的故事
10-07 771
write/read ssize_t write (int fd, const void * buf, size_t count); ssize_t read(int fd, void * buf, size_t count); write()会把参数buf所指的内存写入count个字节到参数放到所指的文件/缓冲区内,即将用户缓冲区当的内容放入到内核缓冲区(socket缓冲区)当。当内核缓冲区已满时,write函数会阻塞。 read()会把参数fd所指的文件传送count 个字节到buf 指针所指
linux socket read write,socket编程writereadsendrecv之间的区别
weixin_28858229的博客
05-15 1056
http://blog.csdn.net/petershina/article/details/7946615一旦,我们建立好了tcp连接之后,我们就可以把得到的fd当作文件描述符来使用。由此网络程序里最基本的函数就是readwrite(int fd, const void*buf,size_t nbytes);write的返回值大于0,表示写了部分或者是全部的数据. 这样我们用一个while循...
read/witer和recv/send区别
04-07
read/writerecv/send都是用于在网络编程进行数据传输的函数。它们之间的区别如下: 1. read/write是UNIX系统的函数,而recv/send是POSIX标准定义的函数。 2. read/write是对文件描述符进行读写操作的函数,...
Linux系统调用-- recv/recvfrom 函数详解
03-28
从套接字上接收一个消息。对于recvfrom ,可同时应用于面向连接的和无连接的套接字。recv一般只用在面向连接的套接字,几乎等同于recvfrom,只要将recvfrom的第五个参数设置NULL。 如果消息太大,无法完整存放在所提供的缓冲区,根据不同的套接字,多余的字节会丢弃。 假如套接字上没有消息可以读取,除了套接字已被设置为非阻塞模式,否则接收调用会等待消息的到来。
【socket】 readrecv区别writesend区别
数字人生
08-11 2038
1.问chatGPT应用:socket readrecv区别? 2.问chatGPT应用:socket writesend区别?
Linux网络通信 --- send recv使用
12-30 864
原文地址:TCP之深入浅出sendrecv作者:weizhulinux 本篇我们用一个测试机上的阻塞socket实例来说明主题。文章所有图都是在测试系统上现截取的。 需要理解的3个概念 1. TCP socket的buffer 每个TCP socket在内核都有一个发送缓冲区和一个接收缓冲区,TCP的全双工的工作模式以及TCP的流量(拥塞)控制便是依赖于这两个独立的buffer以及buffer的填充状态。接收缓冲区把数据缓存入内核,应用进程一直没有调用recv()进行读取的话,此数据..
linux 内核 send,linux内核sendrecv函数详解
weixin_39555179的博客
05-06 200
1.简介#includessize_trecv(intsockfd,void*buff,size_tnbytes,intflags);ssize_tsend(intsockfd,constvoid*buff,size_tnbytes,intflags);sendrecv的前3个参数等同于readwrite;flags参数值为0或:flags说明recvsend...
Linux下,write/readrecv/sendrecvfrom/sendto的区别
雪飞_海
01-06 3136
先说概念和应用场景:read/wirte是通用的文件描述符操作;recv/send 通常应用于TCP;recvfrom/sendto通常应用于UDP。 1. read/write ssize_twrite(int fd, const void*buf,size_t nbytes); ssize_t read(int fd,void *buf,size_t nbyte); write函数是将buf的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1. 并设置errno变量.
linux C语言socket函数recv
最新发布
数字人生
01-20 2621
recv函数是在 Linux C 语言网络编程用于从已连接的套接字接收数据的函数。它通常与 TCP 连接一起使用,但也可以用于 UDP(尽管对于 UDP,更常使用recvfrom,因为它还可以接收发送方的地址信息)。
linux send and recv详解
@奮 鬥@的专栏
02-13 1330
一、send函数  int send( SOCKET s,      const ch一、send函数  int send( SOCKET s,      const char FAR *buf,      int len,      int flags );       不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。 客户程序一般用send
UNIX网络编程-recvsendreadwrite之间的联系与区别
Maple的博客
03-13 1083
原文链接:http://www.cnblogs.com/mhscn/p/3911284.htmlinclude <unistd.h>ssize_t read(int fd, void *buf, size_t nbyte); read()函数是负责从fd读取内容。当读成功时,read()返回实际所读的字节数,如果返回的值是0,表示已经读到文件的结束了,小于0表示出现了错误。如果错误为EINTR说明
readwrite函数
07-13
函数的区别 sendrecv函数是用于网络编程的数据传输,send函数用于将数据从本地主机发送到远程主机,而recv函数则用于从远程主机接收数据到本地主机。 writeread函数则是用于文件操作的数据读写,write函数用于将数据写入文件,而read函数则用于从文件读取数据。 两者的区别在于,sendrecv函数是用于网络编程的数据传输,而writeread函数则是用于文件操作的数据读写。此外,sendrecv函数是基于套接字的,而writeread函数则是基于文件描述符的。
写文章

热门文章

  • 如何删除linux系统下的非空目录 13426
  • printf怎么输出? 如何正确使用%s,%c,%d,%p?=>这篇详解用法 12355
  • 如何判断自己的qt版本呢? 7635
  • Github仓库中怎么新建文件夹、Github的项目中如何上传图片 7598
  • 发现在proteus中截图后,鼠标移不出那个框了?该怎么办? 6126

分类专栏

  • Linux 85篇
  • Qt 48篇
  • C# 4篇
  • Git与GitHub 8篇
  • 共享单车 12篇
  • electron 5篇
  • vtk 6篇
  • opengl 23篇
  • 计算机网络_网络协议从入门到底层原理 19篇
  • 刷遍蓝桥杯 50篇
  • 单片机 2篇
  • MySQL8.0 6篇
  • 树莓派 1篇
  • 数据结构-c与c++分开写 14篇
  • 力扣刷题 22篇
  • C/C++底层逻辑 23篇
  • 计算机组成原理与汇编 4篇
  • c/c++知识二次稳固 92篇
  • java萌新入门 14篇
  • python萌新入门 9篇

最新评论

  • cmake报错:CMake Error at /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:603 (message)...

    踏过山河,踏过海: 强的表情包

  • cmake报错:CMake Error at /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:603 (message)...

    肝帝永垂不朽: 哈哈,解决了回来答复

  • cmake报错:CMake Error at /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:603 (message)...

    踏过山河,踏过海: 肝帝永垂不朽

  • cmake报错:CMake Error at /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:603 (message)...

    肝帝永垂不朽: 还没解决表情包表情包表情包

  • cmake报错:CMake Error at /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:603 (message)...

    踏过山河,踏过海: 错误原因不一致,最后怎么解决了

大家在看

  • 【最新原创毕设】基于JSP+SSM的民宿预约平台+79197(免费领源码)可做计算机毕业设计JAVA、PHP、爬虫、APP、小程序、C#、C++、python、数据可视化、大数据、文案 1021
  • ros2 topic hz异常排查 94
  • SSM自动出卷考试系统ty46t 文件下载
  • 深入理解 Transformer 结构,此篇 PyTorch 实现为你解惑 ——PyTorch 实现 Transformer 应用实例展示 1400
  • 万界星空科技铜加工行业的MES系统解决方案 354

最新文章

  • 【C++】set_intersection求交集
  • 【C++常见错误】0xC0000005: 读取位置 0x00000000 时发生访问冲突
  • [CS报错] error CS1617: /langversion 的选项“12”无效。使用 “/langversion:?“ 列出支持的值
2024
10月 12篇
09月 9篇
08月 4篇
07月 9篇
06月 4篇
04月 11篇
03月 8篇
01月 13篇
2023年148篇
2022年113篇
2021年76篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏过山河,踏过海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

玻璃钢生产厂家图案玻璃钢雕塑秦皇岛玻璃钢雕塑设计公司玻璃钢雕塑着色用什么漆延安校园玻璃钢雕塑制作商场美陈费费用营口玻璃钢雕塑生产厂家绍兴玻璃钢雕塑厂广州玻璃钢卡通动物雕塑南昌景观玻璃钢雕塑制作商场美陈装置三门峡镜面玻璃钢仿铜雕塑厂家杭州大型玻璃钢雕塑摆件曲靖玻璃钢雕塑报价卡通雕塑玻璃钢哪里的好河南装饰商场美陈售价江西卡通玻璃钢动物长颈鹿雕塑红色玻璃钢卡通雕塑代理价格长乐玻璃钢雕塑卡通雕塑玻璃钢利润怎么样节庆商场美陈报价扬州玻璃钢雕塑供应厂家贵阳佛像玻璃钢雕塑贵州户外玻璃钢雕塑宣威市玻璃钢雕塑设计哪里有卖商场美陈的基本材质河北室内商场美陈厂家供应湖北高跟鞋玻璃钢雕塑云南玻璃钢仿铜雕塑厂家南京浦口商场美陈观音玻璃钢雕塑生产厂家香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化