为了UDT的下一个版本越做越好,我把这个帖子转过来,里面提到了UDT的3个问题(可能是问题), 希望有参考意义。
下面是原帖:
基于UDP实现的UDT,在NAT下的数据传输有着独特的优势。 最近对于UDT实现P2P下载,传输效率还不错,唯一的缺陷就是其传输过程会出现异常的错误情况导致程序崩溃。经过仔细的调试,发现2个问题:1. common.cpp:219 uint64_t CTimer::getTime() 的有安全隐患在Windows平台下采用LARGE_INTEGER ccf; if (QueryPerformanceFrequency(&ccf)) { LARGE_INTEGER cc; QueryPerformanceCounter(&cc); return (cc.QuadPart / ccf.QuadPart) * 1000000ULL + (cc.QuadPart % ccf.QuadPart) / (ccf.QuadPart / 1000000); }实现时,在连续两次很短时间内调用会出现时钟频率的误差而出现逻辑错误。如 core.cpp:554 void CUDT::connect(const sockaddr* serv_addr) 实现 uint64_t entertime = CTimer::getTime(); if (CTimer::getTime() - entertime > timeo) { // timeout e = CUDTException(1, 1, 0); break; } 由于时钟频率的误差,CTimer::getTime()会出现小于entertime的情况而导致uint64_t计算差值溢出而使if (CTimer::getTime() - entertime > timeo)在没有超时的情况下条件成立,而使UDT::connect调用立刻返回 UDT::ERROR 1001(目标网络无法连接)的情况。2.文档中的UDTSOCKET linger 说明有误。core.cpp:100 m_Linger.l_onoff = 1; m_Linger.l_linger = 180;UDT文档中说明UDTSOCKET的linger默认开启1秒的延时。参考 UDT::setsockopt()说明UDT_LINGER linger Linger time on close(). Default 1 second. 实际如代码所示,默认延时竟然是180秒。这样会导致多线程中UDT::close()调用阻塞全局的所有UDTSOCKET的调用(如socket,accept,send,recv等)。从而使程序的吞吐量和性能降到极底的程序(具体如多线程监听服务程序在此过程中阻塞无法接受新的客户端连接请求)。同时,有时会出现 CSndBuffer对象指针已被释放而继续调用ackPack等操作出错的情况,具体的错误原因还未查明。3.数据包发送超时后重发的请求SocketID错误,导致如果连接上去后发的第一个数据包超时后面的数据全部无法接收和发送了。
不好意思,段落没有整理好。
基于UDP实现的UDT,在NAT下的数据传输有着独特的优势。 最近对于UDT实现P2P下载,传输效率还不错,唯一的缺陷就是其传输过程会出现异常的错误情况导致程序崩溃。经过仔细的调试,发现2个问题:
1. common.cpp:219 uint64_t CTimer::getTime() 的有安全隐患
在Windows平台下采用LARGE_INTEGER ccf; if (QueryPerformanceFrequency(&ccf)) { LARGE_INTEGER cc; QueryPerformanceCounter(&cc); return (cc.QuadPart / ccf.QuadPart) * 1000000ULL + (cc.QuadPart % ccf.QuadPart) / (ccf.QuadPart / 1000000); }实现时,在连续两次很短时间内调用会出现时钟频率的误差而出现逻辑错误。如 core.cpp:554 void CUDT::connect(const sockaddr* serv_addr) 实现 uint64_t entertime = CTimer::getTime(); if (CTimer::getTime() - entertime > timeo) { // timeout e = CUDTException(1, 1, 0); break; } 由于时钟频率的误差,CTimer::getTime()会出现小于entertime的情况而导致uint64_t计算差值溢出而使if (CTimer::getTime() - entertime > timeo)在没有超时的情况下条件成立,而使UDT::connect调用立刻返回 UDT::ERROR 1001(目标网络无法连接)的情况。
2.文档中的UDTSOCKET linger 说明有误。 core.cpp:100 m_Linger.l_onoff = 1; m_Linger.l_linger = 180;UDT文档中说明UDTSOCKET的linger默认开启1秒的延时。参考 UDT::setsockopt()说明UDT_LINGER linger Linger time on close(). Default 1 second. 实际如代码所示,默认延时竟然是180秒。这样会导致多线程中UDT::close()调用阻塞全局的所有UDTSOCKET的调用(如socket,accept,send,recv等)。从而使程序的吞吐量和性能降到极底的程序(具体如多线程监听服务程序在此过程中阻塞无法接受新的客户端连接请求)。同时,有时会出现 CSndBuffer对象指针已被释放而继续调用ackPack等操作出错的情况,具体的错误原因还未查明。
3.数据包发送超时后重发的请求SocketID错误,导致如果连接上去后发的第一个数据包超时后面的数据全部无法接收和发送了。
谢谢你的信息,我会尽快检查每一个问题。
我改了第一个问题。第二个问题我记得已经改正了(文档没改,但是现在不会block了)。第三个问题还没有搞明白。
谢谢。 还想请问谷先生, 除了下载页面的udt-4.4 release版外, 可不可以下载最新的比较稳定的版本?
你可以试试最新的CVS版本。sendfile/recvfile API有轻微改动,剩下的主要是bug fix。
Log in to post a comment.
为了UDT的下一个版本越做越好,我把这个帖子转过来,里面提到了UDT的3个问题(可能是问题),
希望有参考意义。
下面是原帖:
基于UDP实现的UDT,在NAT下的数据传输有着独特的优势。 最近对于UDT实现P2P下载,传输效率还不错,唯一的缺陷就是其传输过程会出现异常的错误情况导致程序崩溃。经过仔细的调试,发现2个问题:1. common.cpp:219 uint64_t CTimer::getTime() 的有安全隐患在Windows平台下采用LARGE_INTEGER ccf;
if (QueryPerformanceFrequency(&ccf))
{
LARGE_INTEGER cc;
QueryPerformanceCounter(&cc);
return (cc.QuadPart / ccf.QuadPart) * 1000000ULL + (cc.QuadPart % ccf.QuadPart) / (ccf.QuadPart / 1000000);
}实现时,在连续两次很短时间内调用会出现时钟频率的误差而出现逻辑错误。如 core.cpp:554 void CUDT::connect(const sockaddr* serv_addr) 实现 uint64_t entertime = CTimer::getTime(); if (CTimer::getTime() - entertime > timeo)
{
// timeout
e = CUDTException(1, 1, 0);
break;
} 由于时钟频率的误差,CTimer::getTime()会出现小于entertime的情况而导致uint64_t计算差值溢出而使if (CTimer::getTime() - entertime > timeo)在没有超时的情况下条件成立,而使UDT::connect调用立刻返回 UDT::ERROR 1001(目标网络无法连接)的情况。2.文档中的UDTSOCKET linger 说明有误。core.cpp:100 m_Linger.l_onoff = 1;
m_Linger.l_linger = 180;UDT文档中说明UDTSOCKET的linger默认开启1秒的延时。参考 UDT::setsockopt()说明UDT_LINGER linger Linger time on close(). Default 1 second.
实际如代码所示,默认延时竟然是180秒。这样会导致多线程中UDT::close()调用阻塞全局的所有UDTSOCKET的调用(如socket,accept,send,recv等)。从而使程序的吞吐量和性能降到极底的程序(具体如多线程监听服务程序在此过程中阻塞无法接受新的客户端连接请求)。同时,有时会出现 CSndBuffer对象指针已被释放而继续调用ackPack等操作出错的情况,具体的错误原因还未查明。3.数据包发送超时后重发的请求SocketID错误,导致如果连接上去后发的第一个数据包超时后面的数据全部无法接收和发送了。
不好意思,段落没有整理好。
基于UDP实现的UDT,在NAT下的数据传输有着独特的优势。 最近对于UDT实现P2P下载,传输效率还不错,唯一的缺陷就是其传输过程会出现异常的错误情况导致程序崩溃。经过仔细的调试,发现2个问题:
1. common.cpp:219 uint64_t CTimer::getTime() 的有安全隐患
在Windows平台下采用LARGE_INTEGER ccf;
if (QueryPerformanceFrequency(&ccf))
{
LARGE_INTEGER cc;
QueryPerformanceCounter(&cc);
return (cc.QuadPart / ccf.QuadPart) * 1000000ULL + (cc.QuadPart % ccf.QuadPart) / (ccf.QuadPart / 1000000);
}实现时,在连续两次很短时间内调用会出现时钟频率的误差而出现逻辑错误。如 core.cpp:554 void CUDT::connect(const sockaddr* serv_addr) 实现 uint64_t entertime = CTimer::getTime(); if (CTimer::getTime() - entertime > timeo)
{
// timeout
e = CUDTException(1, 1, 0);
break;
} 由于时钟频率的误差,CTimer::getTime()会出现小于entertime的情况而导致uint64_t计算差值溢出而使if (CTimer::getTime() - entertime > timeo)在没有超时的情况下条件成立,而使UDT::connect调用立刻返回 UDT::ERROR 1001(目标网络无法连接)的情况。
2.文档中的UDTSOCKET linger 说明有误。
core.cpp:100 m_Linger.l_onoff = 1;
m_Linger.l_linger = 180;UDT文档中说明UDTSOCKET的linger默认开启1秒的延时。参考 UDT::setsockopt()说明UDT_LINGER linger Linger time on close(). Default 1 second.
实际如代码所示,默认延时竟然是180秒。这样会导致多线程中UDT::close()调用阻塞全局的所有UDTSOCKET的调用(如socket,accept,send,recv等)。从而使程序的吞吐量和性能降到极底的程序(具体如多线程监听服务程序在此过程中阻塞无法接受新的客户端连接请求)。同时,有时会出现 CSndBuffer对象指针已被释放而继续调用ackPack等操作出错的情况,具体的错误原因还未查明。
3.数据包发送超时后重发的请求SocketID错误,导致如果连接上去后发的第一个数据包超时后面的数据全部无法接收和发送了。
谢谢你的信息,我会尽快检查每一个问题。
我改了第一个问题。第二个问题我记得已经改正了(文档没改,但是现在不会block了)。第三个问题还没有搞明白。
谢谢。
还想请问谷先生,
除了下载页面的udt-4.4 release版外,
可不可以下载最新的比较稳定的版本?
你可以试试最新的CVS版本。sendfile/recvfile API有轻微改动,剩下的主要是bug fix。