首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EAGAIN on recv()

EAGAIN on recv()
EN

Stack Overflow用户
提问于 2011-01-24 09:09:47
回答 3查看 10.7K关注 0票数 3

我实现了一个套接字客户端,通过HTTP上的RTSP与ip摄像机进行通信,以便从摄像机获取视频。

要建立与摄像机的通信,首先必须设置HTTP-GET隧道,然后发送RTSP命令。当摄像头断开连接时,程序必须关闭隧道处理程序,完成线程,当进程返回到主函数时,它开始通信(启动踏板等)。

在重新连接时: http-get隧道设置为ok,我的意思是,套接字连接并接收"HTTP OK",因此程序发送RTSP "DESCRIBE“,但recv总是返回EAGAIN错误。我检查wireshar是否从相机发送了DESCRIBE OK响应,但recv从未收到它。

代码如下:

代码语言:javascript
复制
   struct sockaddr_in aServer;
  // string myData;
  char *myData=new char [256];
  connection *c=(connection*)vargp;


   memset(&aServer, 0, sizeof aServer);
   aServer.sin_family = AF_INET;

   aServer.sin_addr.s_addr = inet_addr(c->theServer.c_str());
   if (aServer.sin_addr.s_addr == INADDR_NONE)
   {
     struct hostent *hp;

     hp = gethostbyname(c->theServer.c_str());
     if (hp != NULL)
     {
       memcpy(&aServer.sin_addr, hp->h_addr, hp->h_length);
       aServer.sin_family = hp->h_addrtype;    //Protocol family
     }
     else
           cout << "Failed to resolve " << c->theServer.c_str()  << ": " << hstrerror(h_errno) << endl;
   }

   aServer.sin_port = htons(c->thePort);
   c->fd_get = socket(AF_INET, SOCK_STREAM, 0);

   struct timeval timeout;

   timeout.tv_sec = 5;
   timeout.tv_usec = 0;

  setsockopt(c->fd_get, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

   if (c->fd_get < 0){
    cout << "fd_get < 0"  << endl;
      c->bFin=true;
      c->WakeUP();
      }
   if (connect(c->fd_get, (struct sockaddr *) &aServer, sizeof aServer) < 0){
    cout << "connect fd_get < 0"  << endl;
    c->bFin=true;
    c->WakeUP();
   }
   if(!c->bFin){

    sprintf(myData, "GET %s HTTP/1.1\r\n", c->theURI.c_str());
    sprintf(myData, "%sx-sessioncookie: %s\r\nAccept: application/x-rtsp-tunnelled\r\nAuthorization: %s\r\n\r\n", myData,c->theHTTPSessionId.c_str(), c->addAuthorization(c->aGlobalUsername, c->aGlobalPassword).c_str() );

    cout << myData << endl;
    write(c->fd_get, myData, strlen(myData));

    //LISTENING...
    int theLen=1500; //3000;
    int ret=0;
    unsigned char datosRecibidos[3000];

    int flags =fctl(c->fd_get, F_GETFD;
    if((flags & O_NONBLOCK) == O_NONBLOCK){
        fprint(stderr, "yup, its nonblocking");
    }
    else{
        fprint(stderr, "nope, its blocking");
    }


    while (c->bFin==false){

     ret = read(c->fd_get, ReceivedData, theLen);
    // ret= recvfrom(c->fd_get, ReceivedData, theLen, 0,  (struct sockaddr *) 0, (socklen_t*)0);
     if (ret == 0)
     {
      cout << "Server closed connection: 0" << endl;

    }
      else
      if (ret == -1){
     fprintf (stderr, "\n[%d]: %s %d\n", __LINE__, strerror (errno), errno);

     if(errno==107 ||errno==EAGAIN){
      cout << "errno" << endl;
      c->bFin=true;
      c->WakeUP();
      cout << "vuelta wakeUP" << endl;
      break;// empezar de nuevo
     }else{
      cout << "errno" << endl;

     }

    }
    else{
     //cout << (string)ReceivedData[0]<< endl;
     c->ProcessReceivedData(ReceivedData, ret);
     usleep(10);
    }
   }

   close(c->fd_get);
   c->fd_get = -1;

   }

会不会是超时问题?或者是堆栈问题?我该怎么解决它呢?

提前感谢您的帮助。诚挚的问候。

克里斯蒂娜

EN

回答 3

Stack Overflow用户

发布于 2011-01-24 09:29:45

EAGAIN表示在非阻塞套接字上没有数据可供读取。因此,您应该再次运行recv调用。

你实际上还没有发布足够的代码来表明存在编程错误,尽管我可以问一下,当你检测到连接关闭时,在重新建立一切之前,你是否也关闭了你的连接?

票数 4
EN

Stack Overflow用户

发布于 2011-01-24 09:28:46

您的套接字是否在O_NONBLOCK模式下打开?您可以像这样检查:

代码语言:javascript
复制
int flags = fcntl(fd, F_GETFD);
if ((flags & O_NONBLOCK) == O_NONBLOCK) {
  fprintf(stderr, "Yup, it's nonblocking");
}
else {
  fprintf(stderr, "Nope, it's blocking.");
}

在非阻塞模式下,如果还没有要接收的内容,recv将立即返回,并将errno设置为EAGAIN。

票数 1
EN

Stack Overflow用户

发布于 2013-07-29 22:15:19

在执行每个套接字读取操作之前,我总是使用poll()或select()。

还要测试非阻塞:

代码语言:javascript
复制
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags & O_NONBLOCK) {
     fprintf(stderr, "Yup, it's nonblocking");
   } else {
    fprintf(stderr, "Nope, it's blocking.");
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4777721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档