[socket] receiving function - sock_recv

static int sock_recv(
	int sock_fd,
	size_t size,
	void *buf)
{
	int rc;

retry_after_signal:
	rc = recv(sock_fd, buf, size, MSG_WAITALL);
	if (rc != size) {
		fprintf(stderr, "recv failed: %s, rc=%d\n", strerror(errno), rc);

		if ((errno == EINTR) && (rc != 0))
			goto retry_after_signal;    /* Interrupted system call */
		if (rc)
			return rc;
		else
			return -1;
	}

	return 0;
}
这个函数是一个接收套接字数据的封装函数,它调用 recv 系统调用。它有三个参数:
1. sock_fd: 套接字文件描述符。    
2. size: 要读取的字节数。    
3. buf: 存储接收数据的缓冲区的指针。
函数返回一个整数值,表示读取的字节数,或者 -1 表示出错。如果函数被信号中断,它会在信号清除后重试系统调用。
以下是代码的分析:
1. 定义一个整数变量 rc,用于存储 recv 系统调用的返回值。  
2. 定义一个标签 retry_after_signal,用于标记重试的位置。  
3. 调用 recv 系统调用,将套接字文件描述符 sock_fd、缓冲区指针 buf 和要读取的字节数 size 作为参数传递。同时,设置 MSG_WAITALL 标志,表示如果数据未到达,则等待数据到达。  
4. 检查 recv 的返回值 rc 是否等于要读取的字节数 size。如果不等于,则表示读取失败。  
5. 使用 fprintf 向 stderr 打印错误信息,包括错误代码和错误原因。  
6. 如果错误代码 errno 等于 EINTR 且 rc 不等于 0,则表示系统调用被信号中断,跳转到标签 retry_after_signal 的位置,重试系统调用。  
7. 如果 rc 不等于 0,表示读取成功,返回 rc 作为函数的返回值。  
8. 如果 rc 等于 0,表示套接字已关闭或连接已断开,返回 -1 作为函数的返回值。  
9. 如果读取成功且到达文件尾,返回 0 作为函数的返回值。
这是一个C语言函数,名为sock_recv,它用于从给定的套接字接收数据。这个函数接收三个参数:

sock_fd:这是一个整数,表示要接收数据的套接字文件描述符。
size:这是一个size_t类型的值,表示要接收的最大数据量。
buf:这是一个指向接收数据的缓冲区的指针。
这个函数的执行流程如下:

函数首先尝试通过调用recv函数从给定的套接字接收数据。recv函数的参数包括套接字文件描述符、缓冲区指针、要接收的最大数据量和MSG_WAITALL标志。MSG_WAITALL标志表示recv函数会一直等待,直到接收到请求的数据量。
如果recv函数成功接收了请求的数据量(即返回值rc等于size),那么函数就返回0,表示成功。
如果recv函数没有接收请求的数据量(即返回值rc不等于size),那么函数会检查错误码(通过errno变量)。
如果错误码是EINTR(表示系统调用被中断),并且已经接收了一些数据(即rc大于0),那么函数会跳回第1步,重新尝试接收数据。
如果错误码不是EINTR,或者没有接收任何数据(即rc等于0),那么函数返回rc或者-1,表示错误。
注意,如果函数需要被多次调用才能接收完请求的数据量,那么需要在循环中调用这个函数。同时,如果系统调用被中断,那么可能需要处理这种情况,例如重新尝试接收数据。
`sock_recv`函数的主要功能是接收来自远程主机的数据。它通过`recv`系统调用来完成这个任务。`recv`函数可以从套接字读取数据,并将数据存储在一个缓冲区中。`MSG_WAITALL`标志告诉`recv`函数等待所有的数据都到达后再返回,而不是立即返回。

`sock_recv`函数首先尝试接收指定大小的数据。如果接收到的数据大小与请求的大小不匹配,或者发生错误(如信号中断),那么函数会重新执行`recv`调用,直到接收到完整的数据或者发生其他错误。

如果一切正常,函数返回0,表示已经成功地接收了所有数据。如果发生错误,函数返回-1,并且将错误信息打印到标准错误流。
这段代码是一个名为 `sock_recv` 的函数,用于从套接字接收数据。

函数接受三个参数:
- `sock_fd`:套接字文件描述符,表示要接收数据的套接字。
- `size`:要接收的数据大小(以字节为单位)。
- `buf`:指向接收数据的缓冲区的指针。

函数返回一个整数值,表示接收操作的结果。

函数的实现逻辑如下:
1. 声明一个整型变量 `rc`,用于存储接收操作的结果。
2. 进入一个标签为 `retry_after_signal` 的循环。
3. 调用 `recv` 函数进行接收操作,将数据存储到缓冲区 `buf` 中,接收的数据大小为 `size`。
4. 如果接收到的数据大小不等于 `size`,则打印错误信息,并根据错误码进行处理。
   - 如果错误码为 `EINTR`(中断错误),并且接收到的数据大小不为 0,则继续重试接收操作。
   - 如果接收到的数据大小不为 0,则返回接收到的数据大小。
   - 否则,返回 -1,表示接收失败。
5. 如果接收到的数据大小等于 `size`,则返回 0,表示接收成功。

注意:该函数使用了 `retry_after_signal` 标签来处理中断错误的重试逻辑。

Guess you like

Origin blog.csdn.net/eidolon_foot/article/details/132623451