本帖最后由 stolen007 于 2011-05-29 06:43:39 编辑

解决方案 »

  1.   

    那请问是否会影响效率呢  能否给个具体代码 我加入CRC校验  
    还有 客户端把封包分成100个 万一丢包呢 我要怎么组合 比较有效率
      

  2.   

    我自己的实现代码 但是还没有全部完成 大家帮我看看
    GENERAL_CONTEXT *pGeneralContext=pUdpContext->pGenContext;
    if (pGeneralContext->CrcSize!=crc16((uint8 *)pGeneralContext->buff,sizeof(pGeneralContext->buff)))
    {
    //要求重新发送 设置一个重新发送的标志 
    }
    else
    {
    if(pGeneralContext->TotalNO>0) //判断是否是只有一个 只有一个就不用下面这些操作了
    {
             for ()//循环查找链表
             {
     if (pGeneralContext->Flag=) //循环比较
     {
     //继续插入 要加入10个字节的偏移  判断是否完整
     if ()
     {
                         
     }
     }

             }
    }

    /*否则就是 没有发送错误的 首先判断是否是多个封包pGeneralContext->TotalNO
    判断是否是最新编码  迭代比较pGeneralContext->Flag 如果找不到就新建一个指针保存   
    如果不是就插入到 指定标志的偏移里 判断是否完整了 如果完整则传递给客户 释放掉数据
    */
      

  3.   

    int CIocpServer::IssueUdpSendOp(struct sockaddr_in& remoteAddr,char* buf,unsigned long data_len,SOCKET socket,char * Flag)
    {
    try
    {
    if(m_bStopServer) 
    {
    return FALSE;
    } if(m_pUdpContextManager==NULL)
    throw CSrvException("IssueUdpSendOp m_pUdpContextManager指针非法.",-1); //下面的循环是把数据块分包
    unsigned long leave_bytes = data_len;
    unsigned long trans_bytes = data_len;
    unsigned short counter = 0;
    // unsigned short data_start_index = 0;  //数据真实的起始位
               GENERAL_CONTEXT *pGeneralContext;
       memset((char *)pGeneralContext,0,sizeof(pGeneralContext));
       if (data_len>DEFAULT_UDP_BUFFER_SIZE)
       {
       if ((data_len%DEFAULT_UDP_BUFFER_SIZE)==0)
       {
       pGeneralContext->TotalNO=(data_len/DEFAULT_UDP_BUFFER_SIZE);
       }
       else
       {
                           pGeneralContext->TotalNO=(data_len/DEFAULT_UDP_BUFFER_SIZE)+1;
       }
               
       }
       else
       {
       pGeneralContext->TotalNO=0;
       }
       memcpy(pGeneralContext->Flag,Flag,sizeof(Flag));

    do
    {
     memset((char *)pGeneralContext->buff,0,sizeof(pGeneralContext->buff));
               memset((char *)pGeneralContext->CrcSize,0,sizeof(pGeneralContext->CrcSize));
        memset((char *)pGeneralContext->SortNo,0,sizeof(pGeneralContext->SortNo));
    UDP_CONTEXT* pUdpContext = NULL;
    m_pUdpContextManager->GetContext(pUdpContext);

    if(pUdpContext==NULL)
    throw CSrvException("pUdpContext指针非法.",-1); if(leave_bytes <=DEFAULT_UDP_BUFFER_SIZE) //小于一次发送量
    trans_bytes = leave_bytes;
    else
    trans_bytes = DEFAULT_UDP_BUFFER_SIZE;

    leave_bytes = leave_bytes - trans_bytes; //一次发送后剩余的字节数

    // memcpy(pUdpContext->data_buffer,buf+counter*DEFAULT_UDP_BUFFER_SIZE,trans_bytes);  //拷贝字节数
                 memcpy(pGeneralContext->buff,buf+counter*DEFAULT_UDP_BUFFER_SIZE,trans_bytes);  //拷贝字节数
     pGeneralContext->CrcSize=crc16((uint8 *)pGeneralContext->buff,sizeof(pGeneralContext->buff));
    counter++;
                    pGeneralContext->SortNo=counter;
    ZeroMemory(&pUdpContext->operate_overlapped,sizeof(WSAOVERLAPPED));
    pUdpContext->operate_type = IO_UDP_SEND;
    pUdpContext->socket = socket;
    pUdpContext->operate_buffer.buf =(char *) pUdpContext->pGenContext;
    pUdpContext->operate_buffer.len = trans_bytes;//注意此处的6
    pUdpContext->remote_address = remoteAddr;
    pUdpContext->remote_address_len = sizeof(struct sockaddr);

    DWORD nubmerBytes = 0;
    int err = WSASendTo(
    pUdpContext->socket,
    &pUdpContext->operate_buffer,
    1,
    &nubmerBytes,
    0,
    (struct sockaddr*)&pUdpContext->remote_address,
    sizeof(pUdpContext->remote_address),
    &pUdpContext->operate_overlapped,
    NULL);
    if(SOCKET_ERROR == err && WSA_IO_PENDING != WSAGetLastError())
    {
    ReleaseContext((IO_PER_HANDLE_STRUCT*)pUdpContext);
    throw CSrvException("IssueUdpSendOp->WSASend发生错误.",WSAGetLastError());
    }
    else if(0 == err)
    {
    //还要考虑立即完成的情况
    }

    }while(leave_bytes>0); return TRUE;
    }
    catch(CSrvException& e)
    {
    this->PrintDebugMessage(e);
    if(m_bExceptionStop)
    throw e;
    }
    catch(...)
    {
    string message("IssueUdpSendOp 发生未知异常.");
    PrintDebugMessage(message.c_str());
    if(m_bExceptionStop)
    throw message;
    }
    return FALSE;
    }