UDT bugs? 古先生 请教一个问题

2012-04-03
2014-02-01
  • 今天在用UDT的一个样例,hello world。经过改动后,报出内存错误。
    这个错误我觉得 多线程 对同一段 内存 误操作 引起的。下面把 server和client 的代码 贴出来~

    client:

    ///client
    #include <winsock2.h>
    #include <Ws2tcpip.h>
    #include <iostream>
    #include <udt.h>
    using namespace std;
    using namespace UDT;
    int main()
    {
    while(true)
    {
    UDTSOCKET client = UDT::socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(9000);
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
    memset(&(serv_addr.sin_zero), '\0', 8);
    // connect to the server, implict bind
    if (UDT::ERROR == UDT::connect(client, (sockaddr*)&serv_addr, sizeof(serv_addr)))
    {
    cout << "connect: " << UDT::getlasterror().getErrorMessage();
    return 0;
    }
    char* hello = "hello world!\n";
    if (UDT::ERROR == UDT::send(client, hello, strlen(hello) + 1, 0))
    {
    cout << "send: " << UDT::getlasterror().getErrorMessage();
    return 0;
    }
    UDT::close(client);
    }
    getchar();
    return 1;
    }
    

    server:

    ///server
    #include <winsock2.h>
    #include <Ws2tcpip.h>
    #include <udt.h>
    #include <iostream>
    using namespace std;
    using namespace UDT;
    int main()
    {
    UDTSOCKET serv = UDT::socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(9000);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    memset(&(my_addr.sin_zero), '\0', 8);
    if (UDT::ERROR == UDT::bind(serv, (sockaddr*)&my_addr, sizeof(my_addr)))
    {
    cout << "bind: " << UDT::getlasterror().getErrorMessage();
    return 0;
    }
    UDT::listen(serv, 100);
    int namelen;
    sockaddr_in their_addr;
    UDTSOCKET recver;
    while (true)
    {
    recver = UDT::accept(serv, (sockaddr*)&their_addr, &namelen);
    char ip[16];
    cout << "new connection: " << inet_ntoa(their_addr.sin_addr) << ":" << ntohs(their_addr.sin_port) << endl;
    }
    UDT::close(recver);
    UDT::close(serv);
    getchar();
    return 1;
    }
    

    上面程序的错误 ,希望古先生 能解答。
    (我的编译器是vs2008,同时操作系统是32位win7)

     
  • 不好意思,UDTm会出这样的问题,但是调用UDT5中UDT::clearup()函数,这样的错误就能很好解决。不好意思啊~

     
  • 把UDT5中的样例appclient的connect部分改成下面的方式去写。会出现错误。

    if (UDT::ERROR == UDT::connect(client, peer->ai_addr, peer->ai_addrlen))
    {
    cout << "connect: " << UDT::getlasterror().getErrorMessage() << endl;
    UDT::close(client);
    UDT::cleanup();
    return 0;
    }
    

    这样调用会发生错误。
    请问clearup的调用会有那些限制?该注意些什么?

     
  • 我是这样想 连接不成功,就释放UDT的东西。应该不会对这个做限制吧~可是程序是出错的。

     
  • Yunhong Gu
    Yunhong Gu
    2012-04-04

    先不要使用UDT5,这个还正在开发。你可以使用UDT4的最新版本。

     
  • 古博士,你好,UDT4中我编译udt这个工程的时候出现错误:api.cpp(700) : error C2039: “disable_read”: 不是“CEPoll”的成员
    我将其改为m_EPoll.update_events(listen, ls->m_pUDT->m_sPollID, UDT_EPOLL_IN, false);编译通过之后。

    还是把UDT4中的样例appclient的connect改成下面内容。

    if (UDT::ERROR == UDT::connect(client, peer->ai_addr, peer->ai_addrlen))
    {
    cout << "connect: " << UDT::getlasterror().getErrorMessage() << endl;
    UDT::close(client);
    UDT::cleanup();
    return 0;
    }
    

    依旧是错误的。这是不是UDT的bug呢?
    (我的编译器是vs2008,同时操作系统是32位win7)

     
  • 古博士,今天还遇到了另一个问题。设置setsockopt函数的时候客户端和服务器端均使用UDT_MSS,这个时候在客户端非法断线的时候,服务器端能在30秒的时候检测到断线,但是两端使用UDT_CC时,其自定义拥塞控制算法是样例的cc.h中的CTCP这个类。这个时候客户端再非法断线,服务器端就一直不能检测到客户端的断线情况。
    UDT_CC中的CTCP该如何修改才能使服务器端能检测出这样的非法断线?
    还请古博士帮帮忙~

     
  • sad good
    sad good
    2012-05-14

    herandingyi 你的最后一个问题解决了没??我也是发现了 但是不知道怎么解决

     
  • 没有。只是自己做了很简单的心跳包。

     
  • 今天去网上重新下载了一个udt并做了测试~现在不能连接依然能能做清理了!神奇了~谢谢 古博士把bug修改了!这样我的程序也可以做相应的修改。只是毕业设计的期限也快完了,不知道来得及不~~呵呵。。希望 UDT 越做越好!

     
  • wang hui
    wang hui
    2013-12-31

    我用了最新的udt4.11和udt5这个问题还是存在啊,就是appclient这个例子,UDT::connect()超时,返回-1,接着调用UDT::clieanup()就会报错,我在windows平台就会定位到iterator begin().谢谢希望能帮帮我。

     
    • shiwei0124
      shiwei0124
      2014-01-14

      4.1.1版本我也遇到了这个问题,我是connect一个不存在的ip地址的时候发生的,看了下代码
      主要是CRendezvousQueue::updateConnStatus() 这个里面调用
      CUDT::s_UDTUnited.m_EPoll.update_events(i->m_iID, i->m_pUDT->m_sPollID, UDT_EPOLL_ERR, true);
      的时候,m_pUDT对象已经被销毁了。而这个循环中虽然检测出来这个udt socket 有异常,但是并没有把该对象从m_lRendezvousID 集合中 remove掉。

      我是在void CUDT::connect(const sockaddr* serv_addr)
      这个函数中的代码:
      if (CTimer::getTime() > ttl)
      {
      // timeout
      m_pRcvQueue->removeConnector(m_SocketID); //此处是我添加的代码
      e = CUDTException(1, 1, 0);
      break;
      }

      添加如上的代码应该就可以了,解决这个问题应该有多种改法,不知道我的这种会不会引起其他问题,暂时没发现崩溃的问题了
      希望可以帮到你