Linux中的read/write和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的用法
- 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的区别
- 下面是一个使用read/write进行文件读写操作的例子:
- 下面是一个使用recv/send进行网络通信的例子:
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是用于从 文件描述符 文件描述符 文件描述符或 套接字 套接字 套接字进行数据读写的系统调用。它们之间的主要区别如下:
-
参数不同
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的返回值为已读/写字节数,如果遇到错误则返回-1。
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则用于 网络编程中的套接字通信 网络编程中的套接字通信 网络编程中的套接字通信。 -
处理方式不同
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向服务器发送该消息,并收到服务器的回复。当检测到服务器关闭连接时,程序退出。
这两个程序可以相互通信,实现简单的聊天功能。