我用完成端口写了一个文件传送的程序
传送文件时,每次传送一个结构(功能码+长度+信息),现在问题出现了:
假如一个 “功能码+长度+信息“数据包的长度是4000,在接收过程中有可能一次接受4000或更大 。
当大于4000时,我做如下处理:先取包里的4000,转换成自定义结构,然后再对剩下的转换为自定义结构.发现有以下问题:客户端每次发送的包大小固定,如果以上方式处理,后来接收到的包很可能为上次剩下部分的数据.
这种情况我该如何处理???

解决方案 »

  1.   

    在你得接受侧,应该采取包重新组织办法。
    你的包要加上头尾标志,同时需要校验,一般用CRC校验比较好
      

  2.   

    先发长度,再发数据,接受的时候先收到长度,打开一个buffer,不断渐进接受数据,当长度相等的时候就可以停止接受了,然后再处理buffer
      

  3.   

    void CQoSocket::OnReceive(UINT nIDClient,int read)
    {
    SaveMsg("Read %d bytes",read);
    m_dataClient[nIDClient].m_llRecvedBytes+=LONGLONG(read);
    int nPos=0;
    m_dataClient[nIDClient].m_nGetSize+=read;
    while(m_dataClient[nIDClient].m_nGetSize>0){
    DWORD* pdwMsg = reinterpret_cast<DWORD*>(m_dataClient[nIDClient].m_bufRecv+nPos);
    m_dataClient[nIDClient].m_nMsgId = pdwMsg[0];
    m_dataClient[nIDClient].m_dwMsgSize = pdwMsg[1];
    SaveMsg("Recieve message:%d,message size:%d(m_dataClient[nIDClient].m_nGetSize=%d)",m_dataClient[nIDClient].m_nMsgId,m_dataClient[nIDClient].m_dwMsgSize,m_dataClient[nIDClient].m_nGetSize);
    if(m_dataClient[nIDClient].m_dwMsgSize+2*sizeof(DWORD)<=m_dataClient[nIDClient].m_nGetSize)
    {
    if(m_dataClient[nIDClient].m_nMsgId==Msg_Keep_Alive){
    }else if(m_dataClient[nIDClient].m_nMsgId==Msg_Is_Alive){
    }else if(m_dataClient[nIDClient].m_nMsgId>0 && NULL!=m_pLCom && m_pLCom->m_bCanReceive){ m_pLCom->OnReceive(m_dataClient[nIDClient].m_nMsgId,m_dataClient[nIDClient].m_bufRecv+(nPos+2*sizeof(DWORD)),m_dataClient[nIDClient].m_dwMsgSize,nIDClient);
    }
    m_dataClient[nIDClient].m_nPtr = 0;
    }
    else
    {
    //MoveMemory
    m_dataClient[nIDClient].m_nPtr = m_dataClient[nIDClient].m_nGetSize;
    if(nPos&&m_dataClient[nIDClient].m_nGetSize)
    {
    LDataBuf buffer;
    buffer.GetBuf(m_dataClient[nIDClient].m_nGetSize);
    CopyMemory(buffer.GetData(),m_dataClient[nIDClient].m_bufRecv+nPos,m_dataClient[nIDClient].m_nGetSize);
    CopyMemory(m_dataClient[nIDClient].m_bufRecv,buffer.GetData(),m_dataClient[nIDClient].m_nGetSize);
    }
    break;
    }
    m_dataClient[nIDClient].m_nGetSize-=(2*sizeof(DWORD)+m_dataClient[nIDClient].m_dwMsgSize);
    nPos+=(2*sizeof(DWORD)+m_dataClient[nIDClient].m_dwMsgSize);
    }
    InterlockedExchange(&m_dataClient[nIDClient].m_bReading,FALSE);
    }
      

  4.   

    DentistryDoctor(牙科医生) 你上面的程序应该是阻塞的吧??/
      

  5.   

    不,我就是用的完成端口,要不我将这个Socket类发给你。
      

  6.   

    先发送功能码+长度.客户端应答后服务器端调用transmitfile.客户端收指定长度的内容写入文件.
      

  7.   

    先发长度,再发数据,接受的时候先收到长度,打开一个buffer,不断渐进接受数据,当长度相等的时候就可以停止接受了,然后再处理buffer,这样的方法已经成功了,为什么说“这个没办法?”,实际上超简单,在onrecieve上不能一次接收全部数据,但是recieve会返回一个接收长度,往上加不就可以了?
      

  8.   

    ZHENG017() :transmitfile的用法你有吗?
     有的话还麻烦发给我
    email:[email protected]
    谢谢了
      

  9.   

    我现在很需要这个程序,给我发个源代码,可以不?[email protected]