再次在recv()上

发布于 2024-10-14 05:11:47 字数 3313 浏览 10 评论 0原文

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

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

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

代码如下:

   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;

   }

会不会是超时问题?还是堆栈问题?我该如何解决它?

预先感谢您的帮助。此致。

克里斯蒂娜

I implented a socket client to communicate to an ip camera with RTSP over HTTP to get teh video from the camera.

To stablished the communication with the camera, first i have to set an HTTP-GET tunnel, then send the RTSP commands. When the camera loses the connection, the program has to close the tunnel handler, finish the thread and when the process return to the main function, it begins the communication (start the treads, and so on).

On the reconnection: the http-get tunnel is set ok, i mean, the socket connects and receives a "HTTP OK", so the program sends a RTSP "DESCRIBE" but the recv always return an EAGAIN error. I check with wireshar that the DESCRIBE OK response is sent from the camera, but the recv never gets it.

Here is the code:

   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;

   }

Could it be a timeout problem? or a stack problem? How can i solve it?

Thanks in advance for your help. Best regards.

cristina

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

落花随流水 2024-10-21 05:11:47

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

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

EAGAIN means there is no data available for reading on a non-blocking socket. So, you should run the recv call again.

You haven't actually posted enough code to suggest there is a programming fault, although can I ask if when you detect the connection is closed that you also close down your end as well before re-establishing everything?

一场春暖 2024-10-21 05:11:47

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

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。

Is your socket open in O_NONBLOCK mode? You can check like this:

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.");
}

In nonblocking mode, recv will return immediately with errno set to EAGAIN if there is nothing to receive yet.

终遇你 2024-10-21 05:11:47

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

还要测试非阻塞:

    int flags = fcntl(fd, F_GETFL, 0);
    if (flags & O_NONBLOCK) {
     fprintf(stderr, "Yup, it's nonblocking");
   } else {
    fprintf(stderr, "Nope, it's blocking.");
  }

I would always use poll() or select() before going for each socket read operation.

Also to test for NON-Blocking:

    int flags = fcntl(fd, F_GETFL, 0);
    if (flags & O_NONBLOCK) {
     fprintf(stderr, "Yup, it's nonblocking");
   } else {
    fprintf(stderr, "Nope, it's blocking.");
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文