工具/软件:TI-RTOS
我一直在尝试调试一个问题、似乎 TCP 套接字没有被阻止。 为了获得帮助、我从 tcpEcho 演示中重新创建了症状、并进行了最少的修改。
我首先使用随 TI-RTOS 分发的基本 tcpEcho 演示程序。 实际的演示程序以无限循环方式运行、返回0字节、占用可用的 CPU 周期、直到数据在套接字上。 BSD 套接字(它正在使用它)应阻止、直到套接字上有数据、发生超时或错误(设置了 errno)。
要尝试解决此问题,我修改了 tcpWorker()子例程,以明确使用 MSG_WAITALL,如下所示:
空 tcpWorker (UARg arg0、UARg arg1) {
int clientfd =(int) arg0;
int bytesRcvd;
int bytesSent;
char buffer[TCPPACKETSIZE];
int notdone = true;
System_printf ("tcpWorker:start clientfd = 0x%x\n"、clientfd);
while (notdone){
//应阻止直到 TCPPACKETSIZE 字节被接收或错误。
bytesRcvd = recv (clientfd、buffer、TCPPACKETSIZE、MSG_WAITALL);
System_printf ("已接收%d 个字节。 errno =%d.\n"、bytesRcvd、errno);
System_flush ();
字节 Sent = SEND (clientfd、buffer、字节 Rcvd、0);
if (bytesSent < 0 || bytesSent!= bytesRcvd){
System_printf ("错误:发送失败。\n");
中断;
}
}
system_printf ("tcpWorker stop clientfd = 0x%x\n"、clientfd);
system_flush();
close (clientfd);
}
在这样做之后,请注意 recv()将继续返回0字节,而不会出现错误。
我继续使用标准 select()循环实现对其进行测试(正如我的实际应用使用的那样):
/*
*==== tcpWorker2 ====
*为标准 select()循环修改了 tcpWorker 示例。
*
空 tcpWorker2 (UARg arg0、UARg arg1){
int clientfd =(int) arg0;
int bytesRcvd;
int bytesSent;
char buffer[TCPPACKETSIZE];
int notdone = true;
System_printf ("tcpWorker:start clientfd = 0x%x\n"、clientfd);
while (notdone){
FD_SET READ_FDS;
内部 NFD;
fd_zero (read_fds);
fd_set (clientfd、read_fds);
//超时 NULL 应该永远阻止,但不会阻止
NFD = SELECT (FD_SETSIZE、&READ_FDS、(FD_SET*) 0、(FD_SET *) 0、(struct timeval *) NULL);
if (NFD <0){
system_printf ("tcpWorker2:select()错误。 errno =%d\n"、errno);
中断;
}
否则、如果(NFD = 0){
//选择超时不为 NULL 且没有可用数据时发生
System_printf ("tcpWorker2:select() timeout.\n");
继续;
}
否则{
system_printf ("tcpWorker2:select()返回%d\n"、NFD);
}
if (fd_isset (clientfd、&read_FDS)){
bytesRcvd = recv (clientfd、buffer、TCPPACKETSIZE、0);
System_printf ("tcpWorker2:接收到%d 个字节。 errno =%d.\n"、bytesRcvd、errno);
system_flush();
字节 Sent = SEND (clientfd、buffer、字节 Rcvd、0);
if (bytesSent < 0 || bytesSent!= bytesRcvd){
System_printf ("错误:发送失败。\n");
中断;
}
}
}
system_printf ("tcpWorker stop clientfd = 0x%x\n"、clientfd);
system_flush();
close (clientfd);
}
在 tcpWorker2()示例中,无论端口上是否有数据,select()都将持续返回 NFD 为1,并且永远不会阻止 select()调用无效。
我甚至显式测试了将块的超时设置为5秒(在第3版中)而不是 NULL。
是否有人可以向我指出 select()循环实际阻塞的实际演示?
谢谢、
-Gary