Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recvfrom null缓冲区返回errno EFAULT?_C_Sockets_Null_Asyncsocket_Errno - Fatal编程技术网

Recvfrom null缓冲区返回errno EFAULT?

Recvfrom null缓冲区返回errno EFAULT?,c,sockets,null,asyncsocket,errno,C,Sockets,Null,Asyncsocket,Errno,我正在编程一个UDP非阻塞套接字,我有这个函数 void recvflush(int sockfd) { ssize_t num; while (errno != EWOULDBLOCK) { num = recvfrom(sockfd, NULL, maxpack, 0, NULL, NULL); if (num < 0 && errno != EWOULDBLOCK) error("recvfrom() failed", strerr

我正在编程一个UDP非阻塞套接字,我有这个函数

void recvflush(int sockfd) {
  ssize_t num;
  while (errno != EWOULDBLOCK) {
    num = recvfrom(sockfd, NULL, maxpack, 0, NULL, NULL);
    if (num < 0 && errno != EWOULDBLOCK)
      error("recvfrom() failed", strerror(errno));
  }
}
void recvflush(int sockfd){
ssize_t num;
while(errno!=ewooldblock){
num=recvfrom(sockfd,NULL,maxpack,0,NULL,NULL);
if(num<0&&errno!=ewooldblock)
错误(“recvfrom()失败”,strerror(errno));
}
}
刷新接收缓冲区。然而,当我调用它时,它返回EFAULT(坏地址),并且我确保在调用时设置了sockfd。救命啊

谢谢

您是否有理由认为给
NULL
指针指向
recvfrom
会导致它刷新消息?您告诉它您的缓冲区是
maxpack
字节长的,但随后您给了它一个无效的指针,因此
EFAULT
是正确的且预期的
errno

您应该能够提供零长度来丢弃排队消息:根据
recvfrom(2)
手册页,如果提供的缓冲区长度对于消息来说太短,剩余的数据字节将被丢弃;这应该包括丢弃所有字节

现在,一旦提供了长度为零,还可以提供
NULL
指针,因为在这种情况下缓冲区的任何部分都不需要有效。但这并不是因为
NULL
指针是专门识别的,而是因为提供的长度不需要它的任何部分来指向有效内存。

您是否有理由认为给
NULL
指针指向
recvfrom
会导致它刷新消息?您告诉它您的缓冲区是
maxpack
字节长的,但随后您给了它一个无效的指针,因此
EFAULT
是正确的且预期的
errno

您应该能够提供零长度来丢弃排队消息:根据
recvfrom(2)
手册页,如果提供的缓冲区长度对于消息来说太短,剩余的数据字节将被丢弃;这应该包括丢弃所有字节

现在,一旦提供了长度为零,还可以提供
NULL
指针,因为在这种情况下缓冲区的任何部分都不需要有效。但这并不是因为专门识别
NULL
指针,而是因为提供的长度不需要它的任何部分来指向有效内存。

根据for
recvfrom()
,在以下情况下报告
EFAULT

EFAULT
接收缓冲区指针指向进程的地址空间之外

假设您的
maxpack
变量为>0,
recvfrom()
希望能够将字节写入
buf
参数所指向的缓冲区,但您正在为该参数传递
NULL
,因此出现错误

为什么在调用
recvfrom()
之前要检查
errno
?您应该先调用
recvfrom()
,然后检查是否有错误。并在报告除
eWoldBlock
/
EAGAIN
EINTR
EMSGSIZE
以外的任何错误时停止循环

另外,请记住UDP支持0长度的数据包,在这种情况下,
recvfrom()
将返回0而不是-1,并且不会设置
errno
。确保你在循环中也考虑到了这一点

请尝试以下方法:

void recvflush(int sockfd) {
  ssize_t num;
  do {
    num = recvfrom(sockfd, NULL, 0, 0, NULL, NULL);
    if (num < 0) {
      if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
        break;
      if ((errno != EINTR) && (errno != EMSGSIZE)) {
        error("recvfrom() failed", strerror(errno));
        break;
      }
    }
  }
  while (true);
}
请注意,如果您的套接字不是非阻塞的,则不会报告
eWoldBlock
/
EAGAIN
,因为调用将阻塞直到数据可用,因此您应该使用
select()
(e)poll()
在进入
recvfrom()之前检查套接字是否有任何排队的数据包
循环。

对于
recvfrom()
,在以下情况下报告
EFAULT

EFAULT
接收缓冲区指针指向进程的地址空间之外

假设您的
maxpack
变量为>0,
recvfrom()
希望能够将字节写入
buf
参数所指向的缓冲区,但您正在为该参数传递
NULL
,因此出现错误

为什么在调用
recvfrom()
之前要检查
errno
?您应该先调用
recvfrom()
,然后检查是否有错误。并在报告除
eWoldBlock
/
EAGAIN
EINTR
EMSGSIZE
以外的任何错误时停止循环

另外,请记住UDP支持0长度的数据包,在这种情况下,
recvfrom()
将返回0而不是-1,并且不会设置
errno
。确保你在循环中也考虑到了这一点

请尝试以下方法:

void recvflush(int sockfd) {
  ssize_t num;
  do {
    num = recvfrom(sockfd, NULL, 0, 0, NULL, NULL);
    if (num < 0) {
      if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
        break;
      if ((errno != EINTR) && (errno != EMSGSIZE)) {
        error("recvfrom() failed", strerror(errno));
        break;
      }
    }
  }
  while (true);
}

请注意,如果您的套接字不是非阻塞的,则不会报告
eWoldBlock
/
EAGAIN
,因为调用将阻塞直到数据可用,因此您应该使用
select()
(e)poll()
在进入
recvfrom()之前检查套接字是否有任何排队的数据包
循环。

你从哪里想到可以将
NULL
作为第二个参数传递给
recvfrom()
?这就是它崩溃的原因,因为操作系统无法将接收到的数据写入该“地址”。您可能需要分配一个本地缓冲区(
char-buf[1500];
)来读取数据,即使您只是将数据扔掉。想想看,由于多余的数据(来自用户提供的缓冲区中太大而无法容纳的数据包)被丢弃,我想您可以使用
char-buf[1]进行读取
。您从哪里想到可以将
NULL
作为第二个参数传递给
recvfrom()
?这就是它崩溃的原因,因为操作系统无法将接收到的数据写入该“地址”。您可能需要分配一个本地缓冲区(
char buf[1500];
)来读取数据,即使您只是想扔掉数据