我用socket传输视频数据,服务器端负责不断发送捕捉到的视频数据,
客户端负责接受和播放数据,我是用socket api来写的,
但是客户端只接受了一会儿就死掉了,不知道是怎么回事???
而服务器端还是不断发送数据

解决方案 »

  1.   

    我用socket传输视频数据,服务器端负责不断发送捕捉到的视频数据,
    客户端负责接受和播放数据,我是用socket api来写的,
    但是客户端只接受了一会儿就死掉了,不知道是怎么回事???
    而服务器端还是不断发送数据不发送视频数据的时候要大一些呢??接受端我是这样的:
    for(;;)
    { TotalDataRece =0; //总共已经接受到的数据
    EachDataRece = 0; //每次实际接受到的数据
    EachDataToRead = 0; //每次需要读取的数据
    if((TotalDataRece = recv(recesock, pData, 1024, 0)) <0)
    {
    int a = GetLastError();
    sprintf(szBuf, "WinSock receive error code : %d", WSAGetLastError());
    AfxMessageBox(szBuf);
    closesocket(recesock);
    return -1;
    }
    memcpy(pPlayInfo, pData, 40);
    //接受数据的前40个字节包含了每一视频帧的信息,包括视频数据的大小
    dSize = pPlayInfo->biSizeImage; //每一帧视频数据的大小
    if(dSize == 0)
    {
    AfxMessageBox("receive error !");
    return -1;
    }
    len = dSize + fSize; //每一帧的总共大小,视频头+视频数据
    while (TotalDataRece < len)
    {
    EachDataToRead = min(1024, len-TotalDataRece);
    //每一帧的数据量len在4k-10k之间大小不等。
    if((EachDataRece = recv(recesock, pData+TotalDataRece, EachDataToRead, 0))<0)
    {
    int a = GetLastError();
    sprintf(szBuf, "WinSock receive error code : %d", WSAGetLastError());
    AfxMessageBox(szBuf);
    closesocket(recesock);
    return -1;
    }
    TotalDataRece += EachDataRece; }
    VideoPlayback(pData); //播放收到的每一个视频帧,另外一个函数,

    这是程序的客户端,只能接受大概4-5秒钟,就停在哪儿了,不能正确播放,
    而服务器端还在发送数据,这个是怎么回事,请大侠不吝赐教
      

  2.   

    fsize在哪里定义的,是不是能肯定一定对啊?
    若不对,那在下一次读取pPlayInfo的时候,流数据就不对齐呢,很可能会导致你的VideoPlayback(pData); 函数出错。
    建议楼主检查一下len的值是否大于你pData的缓冲区最大值,可能会造成写越界,导致程序异常。
      

  3.   

    fsize 定义成了一个全局变量,而且已经赋值为40,即是视频头的40个字节
    pData设置为10k的缓冲区了,在程序初始化时就分配好了,该缓冲区只接受一帧数据(每一帧的大小len的值在3k-10k之间不等),调用videoplay(pData)后即回放了该帧后就把pData清空了,即清除掉接受到的数据
    这样pData还是指向该缓冲区的首地址。接着接受下一帧就是在for循环里面。我现在的情况是能接受到4-5秒的视频,即大概有120-150帧的视频数据并能正确显示,
    然后就会停止不动了。我不知道这是怎么回事
      

  4.   

    dSize = pPlayInfo->biSizeImage; //每一帧视频数据的大小
    if(dSize == 0)
    {
    AfxMessageBox("receive error !");
    return -1;
    }
    len = dSize + fSize; //每一帧的总共大小,视频头+视频数据
    len有可能大于你缓冲区的极限。
    加上:
    if(len?>maxbuffer)
    {
    return -1;
    }
    wan
      

  5.   

    网络上收到的数据包不能100%的正确,所以很可能得出的SIZE是个很大的值,这样就会造成内存写越界。
      

  6.   

    每一帧的大小在3k-10k之间,fsize是个40字节的结构,包含了视频数据的信息
    dsize是视频数据的大小。我的缓冲区设在10k以上,我觉得不太可能是这个错误。如果不能保证数据100%正确,那么应该怎么发送呢?是不是分开发送视频头和视频数据?
      

  7.   

    你用的是tcp吧?如果是,你能确保第一个recv()收到到的数据是40字节?如果小于40字节或者是大于40字节怎么办?tcp是数据流,这样接受估计会出问题。int len = 0;
    int framelen = 0;
    int HaveRecvlen = 0;
    char buf[65532];ZeroMemory(buf, 65532);
    for(;;)
    {
       len = recv(recesock, pData, 10280, 0));
    //要考虑len<0的情况
    if ((len + HaveRecvlen) < 40)
    {
       memcpy(buf + HaveRecvlen, pData, len);
       HaveRecvlen += len;
       continue;
    }
    else
    {
       memcpy(buf + HaveRecvlen, pData, len);
       HaveRecvlen += len;
       memcpy(pPlayInfo, buf, 40);
       dSize = pPlayInfo->biSizeImage;
       framelen = dSize + fSize; //每一帧的总共大小,视频头+视频数据   if (HaveRecvlen >= (40+framelen))
       {
         memcpy(pData, buf+40, framelen);//取得视频头+视频数据
         VideoPlayback(pData); //播放收到的每一个视频帧,另外一个函数,     HaveRecvlen = HaveRecvlen - 40 - framelen;
         len = 0;
         memcpy(buf, buf+40+framelen, HaveRecvlen);//不知会不会有问题?
         continue;
        }//end if
        else
       {
          while(1){
             len = recv(recesock, pData, 10280, 0));
             memcpy(buf + HaveRecvlen, pData, len);
             HaveRecvlen += len;
             if (HaveRecvlen >= (40+framelen))
             {
                 memcpy(pData, buf+40, framelen);//取得视频头+视频数据
                 VideoPlayback(pData); //播放收到的每一个视频帧,另外一个函数,             HaveRecvlen = HaveRecvlen - 40 - framelen;
                 len = 0;
                 memcpy(buf, buf+40+framelen, HaveRecvlen);
                 break;
              }//end if
              else
              {
                  continue;
               }
       }//end while      
        }//end else
    }//end else
    }//end for 上面的代码没有经过测试也没有仔细考虑,防错也免了,不知行不行?
      

  8.   

    传送视频最好用udp,效率高,安全,丢掉一些帧可以接受。
      

  9.   

    我发送端是将每一帧的视频头40个字节+视频数据放在一个缓冲区里面,然后一起发送,
    接受端之所以开始接受1024个字节,这个我想把接受到的数据(应该是1024个字节,即使不是也应该大于40个字节吧)前面的40个字节拷贝出来到pplayinfo这个结构中,然后取这个结构中视频数据的大小,接着接受剩余的视频数据。
      

  10.   

    recv(recesock, pData, 1024, 0));中的1024只是表示最多收到1024字节的数据,他实际上收到多少数据是要看recv()的返回值
      

  11.   

    1。你在接收视频包头40个字节的时候,没有判断接收大小是否>=40字节就直接取其中大小长度字段,可能该值所在内存空间是一快未被初始化的空间,这里是个隐患。在INTERNET里任何时候接收数据最好接收后和你想接收的字节数进行一下比对,这才是安全的,哪怕只有40字节之少。
    2。如果不是因为接收数据的问题,你应该从服务器打包发送视频流和播放视频数据这2个方面来进行检查。服务器打包发送是否真的打包真确?发送是否真的全部发完了?还有食品播放是否能够正常播放视频,这些都可以影响而出现你所描述的问题。
      

  12.   

    int len = 0;
    int framelen = 0;
    int HaveRecvlen = 0;
    char buf[65532];ZeroMemory(buf, 65532);
    for(;;)
    {
       len = recv(recesock, pData, 10280, 0));
    //要考虑len<0的情况
    if ((len + HaveRecvlen) < 40)
    {
       memcpy(buf + HaveRecvlen, pData, len);
       HaveRecvlen += len;
       continue;
    }
    else
    {
       memcpy(buf + HaveRecvlen, pData, len);
       HaveRecvlen += len;
       memcpy(pPlayInfo, buf, 40);
       dSize = pPlayInfo->biSizeImage;
       framelen = dSize; //视频数据的长度   if (HaveRecvlen >= (40+framelen))
       {
         memcpy(pData, buf+40, framelen);//取得视频数据
         VideoPlayback(pData); //播放收到的每一个视频帧,另外一个函数,     HaveRecvlen = HaveRecvlen - 40 - framelen;
         len = 0;
         memcpy(buf, buf+40+framelen, HaveRecvlen);//不知会不会有问题?
         continue;
        }//end if
        else
       {
          while(1){
             len = recv(recesock, pData, 10280, 0));
             memcpy(buf + HaveRecvlen, pData, len);
             HaveRecvlen += len;
             if (HaveRecvlen >= (40+framelen))
             {
                 memcpy(pData, buf+40, framelen);//取得视频数据
                 VideoPlayback(pData); //播放收到的每一个视频帧,另外一个函数,             HaveRecvlen = HaveRecvlen - 40 - framelen;
                 len = 0;
                 memcpy(buf, buf+40+framelen, HaveRecvlen);
                 break;
              }//end if
              else
              {
                  continue;
               }
       }//end while      
        }//end else
    }//end else
    }//end for
      

  13.   

    你也没有理解我的意思,你的程序中的第一个recv():recv(recesock, pData, 1024, 0)并不能保证一定收到了40个字节,虽然你希望收到1024字节。