问题 另一端发数据后就是接收不到
代码如下:socksvr = socket(AF_INET,SOCK_DGRAM,0);sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 54321;if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
     return FALSE;if(::WSARecv(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,&overlapped,CompletionRoutine) == SOCKET_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
{
OnError();
return FALSE;
}
}
这样投递一个接收操作成功可为什么接受不到数据呢 ??我用如下方法便可正确接收 while(1)
{
int ll = 0;
ll = ::recvfrom(sock,data,100,0,(sockaddr*)&addr,&addrlen);
data[ll] = '\0';
....
}这是为什么啊    请高手指教

解决方案 »

  1.   

    对方发数据过来时 CompletionRoutine 没有被触发调用
      

  2.   

    WSARecv只收一个字节呀,会不会是因为缓冲不够
      

  3.   

    to  hs_fish(帅帅鱼)第一次投递接收操作在CompletionRoutine 外面投递不行吗我做tcp的重叠io时是可以的啊,和上面一样的tcp模型的就跑的一点问题也没有
    换成udp 形式的就是不行  郁闷啊
      

  4.   

    创建套接字时用WSASocket试一试,或者你把整个程序发给我看看,[email protected]
      

  5.   

    我用WSASocket试了也不行就是另一端发数据来后 CompletionRoutine 没有接收响应
    接收端:
    socksvr = socket(AF_INET,SOCK_DGRAM,0);sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = INADDR_ANY;
    addr.sin_port = 54321;if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
         return FALSE;
    if(::WSARecvFrom(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,(sockaddr*)&addr,&fromlen,&overlapped,CompletionRoutine) == SOCKET_ERROR)
    {
    if(::WSAGetLastError() != WSA_IO_PENDING)
    {
    OnError(pRoutine);
    return FALSE;
    }
    }
    发送端:sockclt = socket(AF_INET,SOCK_DGRAM,0);
    if(sockclt == SOCKET_ERROR)
    {
    AfxMessageBox("create socket error");
    return;
    }
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = INADDR_ANY;
    addr.sin_port = 0;
    nRet = bind(sockclt,(const sockaddr*)&addr,sizeof(sockaddr_in));
    if(nRet == SOCKET_ERROR)
    {
    AfxMessageBox("bind error");
    return;
    }
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = inet_addr("接收端IP");
    addr.sin_port = 54321;
    while(1)
    {
                       CString  ss;
    ss.Format("Thread:%d - send data times:%d\0",id,times);
    int nRet = sendto(sockclt,ss,ss.GetLength(),0,(const sockaddr*)&addr,sizeof(sockaddr_in));
    if(nRet == SOCKET_ERROR)
    {
    CString s;
    s.Format("sendto error socket:%d",::WSAGetLastError());
    pthis->m_list.InsertString(0,s);
    }
      

  6.   

    sockclt = socket(AF_INET,SOCK_DGRAM,0);
    if(sockclt == SOCKET_ERROR)
    {
    AfxMessageBox("create socket error");
    return;
    }
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = INADDR_ANY;
    addr.sin_port = 0;
    nRet = bind(sockclt,(const sockaddr*)&addr,sizeof(sockaddr_in));
    if(nRet == SOCKET_ERROR)
    {
    AfxMessageBox("bind error");
    return;
    }        //addr1 与addr是不同的地址结构,你弄混淆了,
            // addr1是服务器地址结构,也就是接收数据的地址结构
            // addr为本地client的地址结构,也就是你建立socket后
            // 感兴趣的地址结构 
    addr1.sin_family = AF_INET;
    addr1.sin_addr.S_un.S_addr = inet_addr("接收端IP");
    addr1.sin_port = 54321;
    while(1)
    {
                       CString  ss;
    ss.Format("Thread:%d - send data times:%d\0",id,times);
    int nRet = sendto(sockclt,ss,ss.GetLength(),0,(const sockaddr*)&addr1,sizeof(sockaddr_in));
    if(nRet == SOCKET_ERROR)
    {
    CString s;
    s.Format("sendto error socket:%d",::WSAGetLastError());
    pthis->m_list.InsertString(0,s);
    }
      

  7.   

    to  gdy119(夜风微凉) 对啊 我的发送端(客户机)先帮定到一个空的地址addr  然后向服务器addrl 发送数据   接着再等待服务器回应我现在的问题就是 我在服务器端 用 while(1){ recvfrom(...)}  就能接收到数据但是用 事先投递 WSARecvFrom 就接收内不到数据  我用同样的方式 但采用 tcp 的话 投递 WSARecv 后就能接到数据  可udp话就是不行
      

  8.   

    WSARecvFrom
    函数用对了吗?
      

  9.   

    哦,你程序是用UDP传数据,UDP数据报是很容易丢失的
    当你while(1){recvfrom()}的时候是没有问题的因为你一直在接收
    但是当你WSARecvFrom()的时候,有可能数据应该丢失了你才投递的
    操作,而且如果缓冲区满,WSARecvFrom()投递一次后,在投递也会失败
      

  10.   

    刚才又试了一下  总结一下:对tcp:先建立服务端监听套接字
    socksvr = socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = INADDR_ANY;
    addr.sin_port = 54321;
    if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
    return FALSE;
    if(::listen(socksvr,5) == -1)
    return FALSE;
    thrhandle = ::CreateThread(NULL,0,AcceptProc,this,0,NULL);
    return TRUE;监听线程:
    DWORD WINAPI AcceptProc(LPVOID lParam)
    {
    TestSvr* pSvr = (TestSvr*)lParam;

    static int acceptnum = 0;
    sockaddr_in addr;
    int naddrlen = sizeof(sockaddr_in); while(TRUE)
    {
    SOCKET sock = ::accept(pSvr->socksvr,(sockaddr*)&addr,&naddrlen);
    TRACE("");
    CString s;
    s.Format("新连接: %d",sock);
    g_list->InsertString(0,s);

    if(sock == SOCKET_ERROR)
    {
    CString s;
    s.Format("错误: %d",::WSAGetLastError());
    g_list->InsertString(0,s);
    //return -1L;
    continue;
    } if(!pSvr->AddItem(sock,0,0))  //投递一个 WSARecv操作
    {
    AfxMessageBox("add socket error!");
    }
    }
    return 0L;
    }
    BOOL AddItem(SOCKET sock,int type,LPARAM lParam)
    {
        .....
        if(::WSARecv(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,&overlapped,CompletionRoutine) == SOCKET_ERROR)
    {
    if(::WSAGetLastError() != WSA_IO_PENDING)
    {
            TRACE("PostRead WSARecv Error!");
    return FALSE;
    }
    }
    }然后客户端所发送的数据都能接收到 且做了回应
    奇怪的是 我都没用 SleepEx 代码居然跑的好好的??
    对UDP:建立服务端套接字
    socksvr = ::WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED); sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.S_un.S_addr = INADDR_ANY;
    addr.sin_port = 54321; if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
    return FALSE; AddItem(socksvr,1,this);  //投递 WSARecvFromBOOL AddItem(....)
    {
      .....
       if(type == 1)
      {
          int fromlen = sizeof(SOCKADDR_IN);
    if(::WSARecvFrom(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,(sockaddr*)&addr,&fromlen,&overlapped,CompletionRoutine) == SOCKET_ERROR)
    {
    if(::WSAGetLastError() != WSA_IO_PENDING)
    {
    return FALSE;
    }
    }
       }
    }加上 SleepEx   //下面这样行吗??
    DWORD WINAPI ThreadProc(LPVOID lParam)
    {
    while(g_bRun)
    {
    ::SleepEx(50,TRUE);
    }
    }然后客户端向服务端发送数据就是收不到   奇怪对tcp 我都没调用到 SleepEx 它却跑的很好???
    接着改了一下代码  终于可接收到UDP数据: 
    把对服务端套接字接收操作的投递放到ThreadProc中去DWORD WINAPI ThreadProc(LPVOID lParam)
    {
    while(g_bRun)
    {
                      //只要投递过一次下句就不执行了
                      if(服务端套接字 没有投递过)
                         AddItem(sock,1,0);
                      
    ::SleepEx(50,TRUE);
    }
    }
    完成例程:
    void CALLBACK CompletionRoutine(DWORD dwError,DWORD dwByteTrans,LPWSAOVERLAPPED lpOverlapped,DWORD dwFlag)
    {
    DWORD dwBtyeTrans = 0;
    DWORD dwData = 0;        ....... if(dwByteTrans == 0)
    {
    return;
    }
    if(dwError != 0 )
    {
    return;
    } switch(所投递的操作类型)
    {
    case e_read:
    {
    //回应客户机...
    if(是 tcp类型)
    {
    if(::WSARecv(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,&overlapped,CompletionRoutine) == SOCKET_ERROR)
    {
    if(::WSAGetLastError() != WSA_IO_PENDING)
    {
    return;
    }
    }
    }
    if(是 udp类型)
    {
    int fromlen = sizeof(SOCKADDR_IN);
    if(::WSARecvFrom(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,(sockaddr*)&addr,&fromlen,&overlapped,CompletionRoutine) == SOCKET_ERROR)
    {
    if(::WSAGetLastError() != WSA_IO_PENDING)
    {
    return;
    }
    }
    }
    }
    break;
    case e_write:
    {
    //通知多少数据发送完毕...
    }
    break;
    default:
    return;
    }
    }出现上述这样的情况 请各位大侠帮小弟解释一下把