写了一个客户端程序,向服务器请求数据,用的是udp协议,socket编程。其中第一了两个套接字,sock1、sock2,其中sock1绑定1201端口负责向服务器发送请求命令;sock2绑定1202端口。现在用sniffer抓到服务器发送过来的数据包,发送到本地的1202端口。我再程序中写了recvfrom();接受数据,可是recvfrom返回值为零。求大侠指教!!!

解决方案 »

  1.   

    这是主要代码:
    DWORD WINAPI RequireImgData(LPVOID lpParameter)
    {
    SOCKET socket = (SOCKET)lpParameter;
    sockaddr_in localaddr,RecvAddr,recvDataAddr; char CommandData[45]={0};
    long recvlen = 0;
    char *recvimagedata = new char[RECVBUFFER]();
    char *imagebuffer = new char[IMAGELEN_YUV422]();
    long imagebuffersize = IMAGELEN_YUV422;
    char *psave = NULL;
    int n = sizeof(RecvAddr);
    psave = imagebuffer; localaddr.sin_family = AF_INET;
    localaddr.sin_addr.S_un.S_addr = inet_addr("169.254.92.111");
    localaddr.sin_port = htons(1092);
    bind(socket, (sockaddr*)&localaddr, n); SOCKET datasocket = ::socket(AF_INET, SOCK_DGRAM, 0);
    recvDataAddr.sin_family = AF_INET;
    recvDataAddr.sin_addr.S_un.S_addr = inet_addr("169.254.92.111");
    recvDataAddr.sin_port = htons(1093);
    bind(datasocket, (sockaddr*)&recvDataAddr, n); //发送请求命令
    Camera_Open(socket);
    StreamGrabber_Open(socket);
    StreamGrabber_PrepareGrab(socket);
    AcquisitionStart_Execute(socket); //while (1)
    //{
    // Acquisition_Execute(socket);
    //}
    //接收数据
    recvfrom(datasocket, CommandData, sizeof(CommandData), 0, (sockaddr *)&RecvAddr, &n);
    do 
    {
    recvlen = recvfrom(datasocket, recvimagedata, RECVBUFFER, 0, (sockaddr *)&RecvAddr, &n);
    if(recvlen >8)
    memcpy_s(psave, imagebuffersize, (recvimagedata + 8), recvlen - 8);
    imagebuffersize -= recvlen;
    psave += recvlen;
    } while (imagebuffersize > 0);

    ::recvfrom(datasocket, CommandData, sizeof(CommandData), 0, (sockaddr *)&RecvAddr, &n);
    closesocket(datasocket);
    delete[] recvimagedata;
    delete[] imagebuffer;
    psave = NULL;
    return 0;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {

    if(!InitSocket())
    printf("InitSocket() ERR\n"); SOCKET s = ::socket(AF_INET, SOCK_DGRAM, 0); CameraAddr.sin_family = AF_INET;
    CameraAddr.sin_port = htons(3956);
    CameraAddr.sin_addr.S_un.S_addr = inet_addr("169.254.92.23"); DWORD dwThread;
    HANDLE hThread = ::CreateThread(NULL,0, RequireImgData, (LPVOID)s, 0, &dwThread);
    //Sleep(1000);
    system("pause");
    return 0;
    }
      

  2.   

    你怎么知道recvfrom没收到数据
      

  3.   

    对代码做了简单注释:
    //请求数据函数
    DWORD WINAPI RequireImgData(LPVOID lpParameter)
    {
    SOCKET socket = (SOCKET)lpParameter;
    sockaddr_in localaddr,RecvAddr,recvDataAddr; char CommandData[45]={0};
    long recvlen = 0;
    char *recvimagedata = new char[RECVBUFFER]();
    char *imagebuffer = new char[IMAGELEN_YUV422]();
    long imagebuffersize = IMAGELEN_YUV422;
    char *psave = NULL;
    int n = sizeof(RecvAddr);
    psave = imagebuffer; //绑定发送命令套接字
    localaddr.sin_family = AF_INET;
    localaddr.sin_addr.S_un.S_addr = inet_addr("169.254.92.111");
    localaddr.sin_port = htons(1092);
    bind(socket, (sockaddr*)&localaddr, n);

    //绑定接受数据套接字
    SOCKET datasocket = ::socket(AF_INET, SOCK_DGRAM, 0);
    recvDataAddr.sin_family = AF_INET;
    recvDataAddr.sin_addr.S_un.S_addr = inet_addr("169.254.92.111");
    recvDataAddr.sin_port = htons(1093);
    bind(datasocket, (sockaddr*)&recvDataAddr, n); //发送请求命令
    Camera_Open(socket);
    StreamGrabber_Open(socket);
    StreamGrabber_PrepareGrab(socket);
    AcquisitionStart_Execute(socket); //接收数据
    recvfrom(datasocket, CommandData, sizeof(CommandData), 0, (sockaddr *)&RecvAddr, &n);
    do 
    {
    recvlen = recvfrom(datasocket, recvimagedata, RECVBUFFER, 0, (sockaddr *)&RecvAddr, &n);
    if(recvlen >8)
    memcpy_s(psave, imagebuffersize, (recvimagedata + 8), recvlen - 8);
    imagebuffersize -= recvlen;
    psave += recvlen;
    } while (imagebuffersize > 0);

    ::recvfrom(datasocket, CommandData, sizeof(CommandData), 0, (sockaddr *)&RecvAddr, &n);
    closesocket(datasocket);
    delete[] recvimagedata;
    delete[] imagebuffer;
    psave = NULL;
    return 0;
    }//主函数
    int _tmain(int argc, _TCHAR* argv[])
    {

    if(!InitSocket())
    printf("InitSocket() ERR\n"); SOCKET s = ::socket(AF_INET, SOCK_DGRAM, 0); //服务器信息
    CameraAddr.sin_family = AF_INET;
    CameraAddr.sin_port = htons(3956);
    CameraAddr.sin_addr.S_un.S_addr = inet_addr("169.254.92.23"); DWORD dwThread;
    HANDLE hThread = ::CreateThread(NULL,0, RequireImgData, (LPVOID)s, 0, &dwThread);//启动请求数据线程
    //Sleep(1000);
    system("pause");//等待
    return 0;
    }
      

  4.   

    循环次数由imagebuffersize控制的,debug调试中,recvfrom返回值为0,循环几次后进入等待。接收端口没有问题,sniffer抓包,服务器向本地的1093端口发送了数据。
      

  5.   

    通过把recvDataAddr.sin_addr.S_un.S_addr = inet_addr("169.254.92.111");
    改成recvDataAddr.sin_addr.S_un.S_addr = INADDR_ANY;
    解决了,谢谢各位!
      

  6.   

    地址没有错误,本机地址是169.254.92.111
    不太清楚为什么改成INADDR_ANY 就好了
      

  7.   

    追问大家一个问题(解决了依旧给分):
    为什么程序在recvfrom处一直阻塞,一直不返回,按道理不是2秒后返回吗?代码如下:
    fd_set fdRead;
    fd_set fdSocket;
    FD_ZERO(&fdSocket);
    // FD_SET(socket, &fdSocket);
    FD_SET(datasocket, &fdSocket); timeval timeout;
    timeout.tv_sec = RESPONSETIME;//RESPONSETIME = 2 while (true)
    {
    fdRead = fdSocket;
    int nRet = ::select(0, &fdRead, NULL, NULL, &timeout);
    if(nRet >0)
    {
    for(int i = 0; i<(int)fdSocket.fd_count; i++)
    {
    if (FD_ISSET(datasocket, &fdRead))
    {
    if (fdSocket.fd_array[i] == datasocket)
    {
    ::recvfrom(datasocket, CommandData, sizeof(CommandData), 0, (sockaddr *)&RecvAddr, &n);
    do 
    {
    memset(recvimagedata, 0, RECVBUFFER);
    recvlen = ::recvfrom(datasocket, recvimagedata, RECVBUFFER, 0, (sockaddr *)&RecvAddr, &n);
    if(recvlen >8)
    memcpy_s(psave, imagebuffersize, (recvimagedata + 8), recvlen - 8);
    imagebuffersize -= recvlen;
    psave += recvlen;
    } while (imagebuffersize > 0);
    ::recvfrom(datasocket, CommandData, sizeof(CommandData), 0, (sockaddr *)&RecvAddr, &n);
    }
    }
    }
    }
    }
      

  8.   

    recvDataAddr.sin_addr.S_un.S_addr = inet_addr("169.254.92.111");
    你要知接受本机的话应该是
    inet_addr("127.0.0.1"); 169是内网私有,你很难查到问题出在哪