套接字:我的select()函数逻辑有未定义的行为
Sockets: my select() function logic has undefined behavior
我实现了一个从一个套接字接收和从另一个套接字发送/接收的程序。
为此,我使用select()的轮询,在套接字1中,我以高数据速率接收数据,而在另一个套接字中,我从第一个套接字接收周期性消息和数据接收请求。
当没有"来自套接字2"的请求将数据从套接字1委托给套接字2时,我从套接字1正常接收数据,没有问题。然而,假设我在套接字1中接收数据时收到了两个请求"套接字2",第二个请求中断了数据接收,好像它无法再跟上速率"速率不高,实际上只有150 Hz"。
我在main()中做的伪代码:
fd_set readfds, rd_fds, writefds, wr_fds;
struct timeval tv;
do
{
do
{
rd_fds = readfds;
wr_fds = writefds;
FD_ZERO (&rd_fds);
FD_SET (sock1, &rd_fds);
FD_SET (sock2, &rd_fds);
FD_SET (sock1, &wr_fds);
tv.tv_sec = 0;
tv.tv_usec = 20;
int ls = sock2 + 1;
rslt = select (ls, &rd_fds, &wr_fds, NULL, &tv);
}
while (rslt == -1 && errno == EINTR);
if (FD_ISSET (sock1, &rd_fds))
{
rs1 = recvfrom (sock1, buff, size of the buff, ....);
if (rs1 > 0)
{
if (rs1 = alive message)
{
/* system is alive; */
}
else if (rs1 == request message)
{
/* store Request info (list or vector) */
}
else {}
}
}
if (FD_ISSET (StructArg.sock2, &rd_fds))
{
rs2 = recv (sock2, ..., 0);
if (rs2 > 0)
{
if ( /* Message (high rate) is from sock 2 */ )
{
/* process this message and do some computation */
int sp1 = sendto (sock1, .....);
if (sp1 < 0)
{
perror ("Failed data transmission ");
}
else
{
/* increase some counters */
}
}
}
}
if (FD_ISSET (sock1, &wr_fds))
{
/*
if there info stored in the list
do some calculaitons then send to sock 1
*/
if (sendto (sock1, ... ...) < 0)
{
perror ("Failed data transmission");
}
else
{
/* increase counter */
}
}
FD_CLR (sock1, &rd_fds);
FD_CLR (sock2, &rd_fds);
}
while (1);
同样,问题是,如果从sock2接收到请求,为什么从sock1的接收会中断,而我从sock1接收(快速消息),我希望基于消息中的时间戳在输出中交错消息。
注意,几乎所有的套接字函数都可以阻止执行,除非您使用O_NONBLOCK选项创建了套接字:
http://pubs.opengroup.org/onlinepubs/009695399/functions/sendto.html
您还必须处理recvfrom只给您部分读取的情况,除非您使用MSG_WAITALL:
http://pubs.opengroup.org/onlinepubs/009695399/functions/recvfrom.html
就我个人而言,我会使用一个多线程实现,它可以让线程在每个套接字上等待数据。
至于你的最后一个问题:
如果从sock2接收到请求,为什么从sock1的接收会中断,而我从sock1接收(快速消息),我希望根据消息中的时间戳在输出中交错消息。
您是网络堆栈实现的从属者,几乎不能保证在一个套接字上相对于另一个套接字发送或接收数据。您只能保证套接字中的数据是正确排序的。
我期望基于消息中的时间戳在输出中交错消息。
你的期望是没有根据的。如果任一套接字接收缓冲区中有数据,则select()
将激发。这就是你所能依赖的。你不能保证在多个套接字之间观察和排序时间戳。
- 从python调用openMP共享库时,未定义opnMP函数
- 具有外部"c"和程序集的未定义函数
- 已定义函数时出现 G++ "未定义的引用"错误
- 对显式实例化的模板函数的未定义引用
- 编译问题:在函数"_start"中:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 为什么我会收到警告,指出函数已使用但未定义,以及已定义但未使用?
- 2个模板化类的非模板友元函数未定义引用错误
- 使用内联函数 c++ 的未定义引用
- MacOS 上的 Xcode 11 项目不在一个函数中使用 sin 和 cos:未定义的符号"___sincosf_stret"
- 仅在 MacOS 上析构函数的未定义符号
- 如果用户尝试从 JS 调用对象的未定义函数C++则回调C++代码
- C++编译并链接到指向未定义函数的指针
- C++:定义函数时出现未定义函数错误
- 奇怪的未定义函数引用,函数调用C++不存在
- 类型为"double"的输入参数的未定义函数
- Android NDK:创建一个未定义函数的库
- c++ Builder调用未定义函数hypot/ceil/floor/fab
- 通过 GDB 设置断点时未定义函数"d::~d"
- 如何像传递未定义函数一样传递未定义方法
- 确定未定义函数的参数类型