当前位置: 首页 > news >正文

如何让百度快速收录网站国外哪个网站做c 挣钱

如何让百度快速收录网站,国外哪个网站做c 挣钱,四川住房和城乡建设部官方网站,wordpress是用什么开发的<摘要> recv 是 Linux/Unix 系统中用于从已连接的套接字接收数据的系统调用。它是 read 系统调用的套接字特化版本&#xff0c;提供了额外的控制和标志。其核心功能是从 TCP 或已连接的 UDP 套接字的接收缓冲区中读取数据&#xff0c;并将数据存入用户提供的缓冲区。它是…

<摘要>

recv 是 Linux/Unix 系统中用于从已连接的套接字接收数据的系统调用。它是 read 系统调用的套接字特化版本,提供了额外的控制和标志。其核心功能是从 TCP 或已连接的 UDP 套接字的接收缓冲区中读取数据,并将数据存入用户提供的缓冲区。它是所有网络通信中数据接收的基础,广泛应用于客户端和服务器程序中,用于获取对端发送的应用层数据。


<解析>

recv 函数是网络数据流的“接收端”。当数据通过网络到达机器内核后,会被暂存在对应套接字的接收缓冲区中。recv 的工作就是从内核的缓冲区中将这些数据拷贝到应用程序自己定义的内存空间中,以便程序进行处理。

1) 函数的概念与用途
  • 功能:从已连接的套接字接收消息。
  • 场景
    • TCP 客户端/服务器:在成功建立 TCP 连接(connect/accept)后,使用 recv 来读取对方发送的数据流。
    • 已连接的 UDP 套接字:对调用了 connect 指定了对端地址的 UDP 套接字,使用 recv 来接收来自该特定对端的数据报。
    • 不适用:用于未连接的 UDP 套接字(应使用 recvfrom)。
2) 函数的声明与出处

recv 定义在 <sys/socket.h> 头文件中,是 POSIX 标准的一部分。

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
3) 返回值含义与取值范围
  • 成功:返回实际读取到的字节数。这个值可能小于参数 len 指定的缓冲区大小。
  • 返回 0:这意味着对端已经关闭了连接(对于 TCP 来说,收到了 FIN 包)。这是一个重要的信号,应用程序通常应该也关闭本地的这个套接字。
  • 失败:返回 -1,并设置相应的错误码 errno
    • EAGAINEWOULDBLOCK:套接字被设置为非阻塞模式,并且当前接收操作会被阻塞。这不是一个真正的错误,只是提示“请稍后再试”。
    • EINTR:这个调用在阻塞期间被信号中断。通常需要重新调用 recv
    • ECONNREFUSED:对端拒绝连接(通常用于 UDP 或异步错误)。
    • ENOTCONN:套接字未连接。
    • ENOMEM:没有足够的内存来接收消息。
4) 参数的含义与取值范围
  1. int sockfd

    • 作用:一个已连接的套接字的文件描述符。
    • 取值范围:一个由 socket 创建并已成功连接(通过 connectaccept)的有效描述符。
  2. void *buf

    • 作用:指向一段应用程序分配的内存空间的指针,用于存放接收到的数据。
    • 取值范围:指向一块大小至少为 len 的可写内存。
  3. size_t len

    • 作用:指定缓冲区 buf最大长度,即本次调用最多能接收多少字节的数据,防止缓冲区溢出。
    • 取值范围:通常就是 buf 缓冲区的大小。
  4. int flags

    • 作用:修改接收操作行为的标志位。可以通过按位或 | 组合多个标志。
    • 常见取值
      • 0默认行为。阻塞等待,直到有数据可用。
      • MSG_DONTWAIT非阻塞操作。即使没有数据可读,也立即返回,而不是阻塞。失败时设置 errnoEAGAIN/EWOULDBLOCK
      • MSG_PEEK窥探数据。从接收缓冲区中拷贝数据到 buf,但不会将这些数据从缓冲区中移除。下一次调用 recv 还会看到相同的数据。
      • MSG_WAITALL等待全部数据。请求内核等待,直到接收到恰好 len 个字节的数据后才返回。但在某些情况下(如收到信号、连接中断),它仍然可能返回少于 len 的数据。
      • MSG_OOB接收带外数据。用于处理紧急数据。
5) 函数使用案例

示例 1:基础的 TCP 回显服务器(处理接收循环和连接关闭)
此示例展示一个简易的 TCP 服务器,它接收客户端数据并回显。它正确处理了 recv 返回 0 的情况。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 8080
#define BUFFER_SIZE 1024int main() {int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[BUFFER_SIZE] = {0};// 创建套接字文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 强制附加端口,避免 "address already in use" 错误if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定套接字到端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 开始监听if (listen(server_fd, 3) < 0) {perror("listen");exit(EXIT_FAILURE);}printf("Server listening on port %d\n", PORT);// 接受一个传入连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");exit(EXIT_FAILURE);}printf("Connection accepted. Waiting for data...\n");// 接收循环while(1) {// 清空缓冲区memset(buffer, 0, BUFFER_SIZE);// 核心:调用 recv 阻塞等待数据ssize_t bytes_received = recv(new_socket, buffer, BUFFER_SIZE, 0);printf("recv() returned: %zd\n", bytes_received);if (bytes_received > 0) {printf("Received %zd bytes: '%s'\n", bytes_received, buffer);// 回显相同的数据send(new_socket, buffer, bytes_received, 0);printf("Echoed back.\n");} else if (bytes_received == 0) {// 对端关闭了连接printf("Client closed the connection. Closing socket.\n");break;} else {// recv 出错perror("recv failed");break;}}close(new_socket);close(server_fd);return 0;
}

使用 telnet 127.0.0.1 8080 或下面的客户端示例进行测试。

示例 2:简单的 TCP 客户端
此示例展示一个客户端如何使用 recv 接收服务器的响应。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define SERVER_IP "127.0.0.1"
#define PORT 8080
#define BUFFER_SIZE 1024int main() {int sock = 0;struct sockaddr_in serv_addr;char *message = "Hello from client!";char buffer[BUFFER_SIZE] = {0};// 1. 创建套接字if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {perror("Socket creation error");return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 将IP地址从字符串转换为二进制形式if(inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) {perror("Invalid address/ Address not supported");return -1;}// 2. 连接到服务器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {perror("Connection Failed");return -1;}// 3. 发送数据send(sock, message, strlen(message), 0);printf("Hello message sent\n");// 4. 接收服务器的回显数据 (核心: 调用recv)ssize_t bytes_received = recv(sock, buffer, BUFFER_SIZE, 0);if (bytes_received > 0) {buffer[bytes_received] = '\0'; // 确保字符串终止printf("Server echoed: %s\n", buffer);} else if (bytes_received == 0) {printf("Server closed the connection unexpectedly.\n");} else {perror("recv failed");}close(sock);return 0;
}

示例 3:使用 MSG_PEEK 和 MSG_DONTWAIT 标志
此示例演示如何非阻塞地“窥探”接收缓冲区中的数据,而不将其移除。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>int main() {// ... (创建一对已连接的套接字用于演示,省略了socketpair创建代码)// int sockfd[2];// socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd);// 假设 sockfd[0] 和 sockfd[1] 是已连接的一对套接字int recv_sock = sockfd[0]; // 用于接收的套接字int send_sock = sockfd[1]; // 用于发送的套接字const char *message = "Peekaboo!";char buffer[20] = {0};// 1. 向发送端套接字写入数据send(send_sock, message, strlen(message), 0);printf("Sent: '%s'\n", message);// 2. 使用 MSG_PEEK | MSG_DONTWAIT 窥探数据ssize_t peeked_bytes = recv(recv_sock, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT);if (peeked_bytes > 0) {buffer[peeked_bytes] = '\0';printf("Peeked (%zd bytes): '%s'\n", peeked_bytes, buffer);printf("Data is still in the kernel's receive buffer.\n");} else if (peeked_bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {printf("Peek would block (no data available).\n");} else {perror("Peek failed");}// 3. 正常接收数据(这次数据会被移除)memset(buffer, 0, sizeof(buffer));ssize_t real_bytes = recv(recv_sock, buffer, sizeof(buffer), 0);if (real_bytes > 0) {buffer[real_bytes] = '\0';printf("Actually received (%zd bytes): '%s'\n", real_bytes, buffer);}close(recv_sock);close(send_sock);return 0;
}
6) 编译方式与注意事项

编译命令:

# 编译服务器
gcc -o tcp_server tcp_server.c
# 编译客户端
gcc -o tcp_client tcp_client.c
# 编译PEEK示例 (需要补充socketpair的代码)
# gcc -o recv_peek_demo recv_peek_demo.c

注意事项:

  1. 返回值处理永远不要假设 recv 会一次性读完你要求的数据量。必须检查返回值,它告诉你实际读到了多少字节。这对于TCP这种字节流协议至关重要。
  2. 阻塞 vs 非阻塞:默认情况下,套接字是阻塞的。recv 会一直等待,直到有数据可读。如果套接字被设置为非阻塞(O_NONBLOCK),recv 会立即返回,如果没有数据,则返回 -1 并设置 errnoEAGAIN/EWOULDBLOCK
  3. 连接关闭返回值 0 表示对端已正常关闭连接。这是需要处理的重要边界条件,而不是错误。
  4. 缓冲区与字符串recv 接收的是原始字节数据,不会自动在末尾添加字符串终止符 \0。如果你要将接收到的数据当作 C 字符串处理,必须手动添加 buffer[bytes_received] = '\0';
  5. MSG_WAITALL 的误区:即使指定了 MSG_WAITALL,在信号中断、连接错误或进程被杀死的情况下,它仍然可能返回少于请求字节数的数据。不能完全依赖它。
  6. UDP 的使用recv 只能用于已连接 (connected) 的 UDP 套接字。对于未连接的 UDP 套接字,应使用 recvfrom 来同时获取数据和对端地址。
7) 执行结果说明
  • 示例1 & 2
    1. 先运行 ./tcp_server,服务器启动并等待连接。
    2. 再运行 ./tcp_client,客户端连接服务器并发送消息。
    3. 服务器输出:会打印 recv() returned: 18Received 18 bytes: 'Hello from client!',然后将数据回显。
    4. 客户端输出:会打印 Server echoed: Hello from client!
    5. 使用 Ctrl+C 关闭客户端后,服务器会检测到连接关闭 (recv 返回 0),打印关闭信息并退出。
  • 示例3:运行后会展示先窥探到的数据和之后实际接收到的数据是相同的,证明 MSG_PEEK 没有消耗缓冲区中的数据。
8) 图文总结:recv 工作流程
成功拷贝到数据
(字节数 > 0)
接收缓冲区为空
且对端已关闭连接 (FIN)
发生错误
阻塞模式
非阻塞模式
应用程序调用 recv()
内核从套接字接收缓冲区
拷贝数据到用户空间缓冲区 buf
检查拷贝结果
返回实际读取的字节数
返回 0
返回 -1
并设置相应的 errno
套接字模式
是否阻塞?
缓冲区空则睡眠等待
缓冲区空则立即返回 -1 (EAGAIN)
应用程序处理数据
应用程序关闭连接
应用程序根据 errno 处理错误
http://www.dtcms.com/a/583704.html

相关文章:

  • 接送车服务网站怎么做互联网企业网站模板
  • wordpress 语言切换龙岗seo网络推广
  • 怎么验证网站备案密码是否正确什么是网络营销中的终极诉求
  • C语言输入与输出(I/O)
  • seo优化文章网站西安最新出入政策
  • 外管局网站上做预收登记4.1网站建设的基本步骤
  • 网站一级栏目南通网站建设哪家好
  • 数组、列表、集合区别
  • 手机怎样建个人网站微云做网站
  • 鸿蒙更新targetSdkVersion
  • 网站刷链接怎么做的上海做一个公司网站多少钱
  • 建设银行基金网站做图模板网站有哪些
  • 有需要做网站的吗在哪些网站上申请做广告可以在百度引擎能收到关键字
  • wordpress 建站教程申请了域名怎么建网站
  • 二级域名做网站注意龙海市邦策网站建设平台
  • 网站开发看谁的教程网上课程网站
  • 餐饮业网站建设青岛wordpress建站
  • 北海网站网站建设怎样做网络推广成本最低
  • 股票配资网站建设四川建设网站公司
  • 义乌网站开发公司wordpress $wp
  • 高唐做网站建设的公司华为网络营销案例分析
  • 可以做外贸私单的网站wordpress亚马逊
  • 滨州做网站优化太原视频剪辑培训机构哪个好
  • 怎么找网站建设公司产品推广软文200字
  • 江苏昆山网站建设哪些网站用python做服务框架
  • 北京企业网站建设模板网站建设公司 东莞
  • 微信开放平台 网站开发专门做书籍设计的网站
  • 平台建设网站wordpress仿雷锋网
  • 济南网站设计制作要多久php网站的数据库在哪
  • 做淘宝客网站需要多大的数据库建设网站优化