Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/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
Sockets 什么';在C/C+;中调用recvfrom()函数时,读取逻辑是什么+; 我编写了一个C++程序,在这个套接字上创建一个套接字并绑定,以接收ICMP/UDP数据包。我编写的代码如下: while(true){ recvfrom(sockId, rePack, sizeof(rePack), 0, (struct sockaddr *)&raddr, (socklen_t *)&len); processPakcet(recv_size); }_Sockets_Udp_Recv_Icmp_Recvfrom - Fatal编程技术网

Sockets 什么';在C/C+;中调用recvfrom()函数时,读取逻辑是什么+; 我编写了一个C++程序,在这个套接字上创建一个套接字并绑定,以接收ICMP/UDP数据包。我编写的代码如下: while(true){ recvfrom(sockId, rePack, sizeof(rePack), 0, (struct sockaddr *)&raddr, (socklen_t *)&len); processPakcet(recv_size); }

Sockets 什么';在C/C+;中调用recvfrom()函数时,读取逻辑是什么+; 我编写了一个C++程序,在这个套接字上创建一个套接字并绑定,以接收ICMP/UDP数据包。我编写的代码如下: while(true){ recvfrom(sockId, rePack, sizeof(rePack), 0, (struct sockaddr *)&raddr, (socklen_t *)&len); processPakcet(recv_size); },sockets,udp,recv,icmp,recvfrom,Sockets,Udp,Recv,Icmp,Recvfrom,因此,我使用了无休止的while循环来不断地接收消息,但我担心以下两个问题: 1, How long the message would be kept in the receiver queue or say in NIC queue? 我担心如果处理第一条消息的时间太长,那么我可能会错过第二条消息。那么,我应该以多快的速度阅读后阅读 2,如何防止读取重复消息? i、 接收方队列是否知道我,当我的线程读取完第一条消息时,队列是否会自动给我第二条消息?或者说,当我阅读第一条消息时,第一条消息将

因此,我使用了无休止的while循环来不断地接收消息,但我担心以下两个问题:

1, How long the message would be kept in the receiver queue or say in NIC queue?
我担心如果处理第一条消息的时间太长,那么我可能会错过第二条消息。那么,我应该以多快的速度阅读后阅读

2,如何防止读取重复消息?

i、 接收方队列是否知道我,当我的线程读取完第一条消息时,队列是否会自动给我第二条消息?或者说,当我阅读第一条消息时,第一条消息将被队列删除,没有人能够再次收到它


另外,我认为while(true)模块不好,任何人都可以给我一个好的建议。(我听到类似轮询模块的声音)。

首先,您应该始终检查
recvfrom
中的返回值。
recvfrom
不太可能失败,但如果失败(例如,如果您稍后实施信号处理,则可能会在
EINTR
中失败),您将处理未定义的数据。当然,返回值也会告诉您收到的数据包的大小

对于问题1,实际答案取决于操作系统。但是,大多数操作系统都会为您缓冲一定数量的数据包。处理传入数据包的操作系统中断处理程序永远不会将其直接复制到应用程序级缓冲区中,因此它总是首先进入操作系统缓冲区。操作系统之前已经注意到您对它感兴趣(通过创建套接字并绑定它,您表达了兴趣),因此它会将指向缓冲区的指针放在与套接字关联的队列上

然后,操作系统代码的另一部分(在中断处理程序完成后)将数据从操作系统缓冲区复制到应用程序内存中,释放操作系统缓冲区,然后从
recvfrom
系统调用返回到程序。如果在您开始处理第一个数据包之前或之后有其他数据包进入,它们也将被放置在队列中

当然,这个队列不是无限的。您很可能可以配置可以保留多少数据包(或多少缓冲区空间),或者是在系统范围级别(考虑linux中的
sysctl
-类型设置),或者是在单个套接字级别(
setsockopt
/
ioctl

如果在调用
recvfrom
时,套接字上已经有排队的数据包,则系统调用处理程序不会阻止您的进程,而是将下一个排队数据包的操作系统缓冲区复制到您的缓冲区中,释放操作系统缓冲区,然后立即返回。只要您能够大致以到达的速度或更快的速度处理传入的数据包,您就不应该丢失任何数据包。(但是,请注意,如果另一个系统正在以非常高的速率生成数据包,则操作系统保留的内存可能会在某个点耗尽,之后操作系统将简单地丢弃超出其资源保留的数据包。)

对于问题2,您将不会收到重复的消息(除非您的机器上游的某些东西确实在复制它们)。一旦队列消息被复制到缓冲区中,它将在返回给您之前被释放。这个信息已经永远消失了

(请注意,可能其他进程也创建了一个套接字,表示对相同数据包感兴趣。该进程还将获得数据包数据的副本,该数据包通常通过引用计数而不是实际复制操作系统缓冲区在操作系统内部处理,尽管应用程序看不到该细节。)在任何情况下,一旦所有感兴趣的进程都收到了数据包,它就会被丢弃。)

while(true)真的一点问题都没有
loop;对于长时间运行的服务器类型程序来说,这是一种非常常见的控制结构。如果您的程序在此期间没有其他需要执行的操作,
while true
允许它在
recvfrom
中阻塞是实现它的最简单、最清晰的方法


(您可以使用
select(2)
poll(2)
调用等待。这允许您同时处理多个文件描述符中的任何一个的等待,或定期“超时”然后去做其他的事情,比如说,但是如果你没有其他事情,你可能需要同时做,这会带来不必要的复杂性。)

首先,你应该总是检查
recvfrom
的返回值。
recvfrom
不太可能失败,但是如果失败了(例如,如果以后执行信号处理,则可能会因
EINTR
而失败)您将处理未定义的数据。当然,返回值也会告诉您所接收数据包的大小

对于问题1,实际答案取决于操作系统。但是,大多数操作系统都会为您缓冲一定数量的数据包。处理传入数据包的操作系统中断处理程序永远不会将其直接复制到您的应用程序级缓冲区中,因此它总是首先进入操作系统缓冲区。操作系统之前已经注意到您r对它感兴趣(通过创建套接字并绑定它,您表达了兴趣),因此它将把指向缓冲区的指针放在与套接字关联的队列上

然后,操作系统代码的另一部分将出现(在中断处理程序完成后)将数据从操作系统缓冲区复制到应用程序内存中,释放操作系统缓冲区,然后从
recvfrom
系统调用返回到程序。如果在开始处理第一个数据包之前或之后有其他数据包进入,它们也将被放入队列中

这个队列当然不是无限的,很可能您可以配置有多少个数据包(或者有多少个数据包)