C++里的发送代码:
// 传送文件
bool __fastcall TfrmSendFile::SendFile(TCustomWinSocket* sClient)
{
if (NULL == g_pBuff)
{
   ReadFile(sClient);
}
int nPacketBufferSize = MAX_PACKET_SIZE - 2 * sizeof(int); // 每个数据包存放文件的buffer大小
// 如果文件的长度大于每个数据包所能传送的buffer长度那么就分块传送
for (int i = 0; i < g_lLength; i += nPacketBufferSize)
{
   CCSDef::TMSG_FILE tMsgFile;
   tMsgFile.tFile.nStart = i;
   if (i + nPacketBufferSize + 1> g_lLength)
   {
    tMsgFile.tFile.nSize = g_lLength - i;
   }
   else
   {
    tMsgFile.tFile.nSize = nPacketBufferSize;
   }
   memcpy(tMsgFile.tFile.szBuff, g_pBuff + tMsgFile.tFile.nStart, tMsgFile.tFile.nSize+1);   
   IssueAuthSendFileRequest(sClient,SERVER_CLIENT_STARTSENDFILE, 0, 0,(char*)(&tMsgFile), NULL);
   Sleep(0.5);
}
delete [] g_pBuff;
g_pBuff = NULL;
return true;
}我跟踪调试过,tMsgFile.tFile.szBuff里存的是我想传的东西,
但是在VC++的接收里,红色字体地方出错。
// 写入文件
bool WriteToFile(CCSDef::TMSG_HEADER *pMsgHeader)
{
assert(NULL != pMsgHeader);
CCSDef::TMSG_FILE* pMsgFile = (CCSDef::TMSG_FILE*)pMsgHeader;
int nStart = pMsgFile->tFile.nStart;
int nSize = pMsgFile->tFile.nSize;
memcpy(g_pBuff + nStart, pMsgFile->tFile.szBuff, nSize);
if (0 == nStart)
{
   printf("Saving file into buffer...\n");
}
memcpy(g_pBuff + nStart, pMsgFile->tFile.szBuff, nSize);
// 如果已经保存到缓冲区完毕就写入文件
if (nStart + nSize >= g_lLength)
{    printf("Writing to disk....\n");
    // 写入文件
    FILE* pFile;
    pFile = fopen(g_szFileName, "w+b");
    fwrite(g_pBuff, sizeof(char), g_lLength, pFile);
    delete [] g_pBuff;
    g_pBuff = NULL;
    fclose(pFile);
    return true;
}
else
  return false;
}这是结构体
// 传送文件
struct TMSG_FILE : public TMSG_HEADER
{
   union     // 采用union保证了数据包的大小不大于MAX_PACKET_SIZE * sizeof(char)
   {
    char szBuff[MAX_PACKET_SIZE];
    struct
    {
     int nStart;
     int nSize;
     char szBuff[MAX_PACKET_SIZE - 2 * sizeof(int)];
    }tFile;
   };
   TMSG_FILE()
    : TMSG_HEADER(MSG_FILE)
   {
   }
};

解决方案 »

  1.   

    IssueAuthSendFileRequest是阻塞方式的吗?
      

  2.   

    这个我还真不太明白。我也是改别人的程序。我想问下   
    CCSDef::TMSG_FILE tMsgFile;
    tMsgFile如何转char * 呢?
      

  3.   

    如果只是memcpy 出错,那应该错在指针吧
    //    assert(g_pBuff);另外,send和recv的代码没有贴出来
    看你的代码,g_pBuff应该不是同一块内存吧(SendFile和WriteToFile中的g_pBuff),如果是同一块的话,当然出错了,因为在SendFile里,文件发送完后,把g_pBuff释放掉了
      

  4.   

    BOOL IssueAuthSendFileRequest(TCustomWinSocket *cas_from, int command, int comid, int nArg1, char *svArg2, char *svArg3)
    {
    unsigned char *buf;
    int buflen,ret;
            if(cas_from==NULL) return FALSE;
            struct bo_command_header *hdr;
    int nArg2Len,nArg3Len;
    buflen=sizeof(struct bo_command_header) + sizeof(int);
    nArg2Len=0;
    nArg3Len=0;
    if(svArg2!=NULL)
            {
    nArg2Len = (lstrlen(svArg2)+1);
    buflen += nArg2Len;
    }
    if(svArg3!=NULL) {
    nArg3Len = (lstrlen(svArg3)+1);
    buflen += nArg3Len;
    } buf=(unsigned char *) malloc(buflen);
    if(buf==NULL) {
    buflen=0;
    return FALSE;
    }
    memset(buf,0,buflen);
    hdr=(struct bo_command_header *)buf;
    hdr->cmdlen=buflen;
    hdr->comid=comid;
    hdr->command=command;
    hdr->flags=CMDFLAG_SENDFILE;
    hdr->nArg1=nArg1;
    hdr->nArg2Len=nArg2Len;
    hdr->nArg3Len=nArg3Len;
    if(svArg2!=NULL) {
    lstrcpyn((char *)buf+sizeof(struct bo_command_header),svArg2,nArg2Len);
    }
    if(svArg3!=NULL) {
    lstrcpyn((char *)buf+sizeof(struct bo_command_header)+nArg2Len,svArg3,nArg3Len);
    }
        try{
            ret=cas_from->SendBuf(buf,buflen);
        }
        __finally{
            free(buf);
            if (ret==buflen)         return TRUE;
        else
            {
            if (ret<0)
            {
                ret=GetLastError();
                char msg[10];
                return FALSE;
            }
            else
            {
                return FALSE;
            }
            }
        }
    }
    这是发送的代码,g_pBuff不是同一块内存,在发送端,转换成char *
      

  5.   

    CCSDef::TMSG_FILE tMsgFile; 
    tMsgFile如何转char * 呢?
    char* pTemp = new char[sizeof(CCSDef::TMSG_FILE)];
    memcpy(pTemp,&tMsgFile,sizeof(CCSDef::TMSG_FILE));
      

  6.   

    1,快速问题定位,查看IssueAuthSendFileRequest(sClient,SERVER_CLIENT_STARTSENDFILE, 0, 0,(char*)(&tMsgFile), NULL); 的返回值
    BOOL bOK=IssueAuthSendFileRequest(sClient,SERVER_CLIENT_STARTSENDFILE, 0, 0,(char*)(&tMsgFile), NULL); 
    if(!bOK) 输出日志信息2,ret=cas_from->SendBuf(buf,buflen); SendBuf是封装过的吗(看上去好象没有)?封装成buf一直发完才返回
    象你这样发送文件,速度太快,SendBuf调用后,返回值往往会小于要发送的数据长度(ret<buflen)3,等待你的接收代码
    按照你发送的代码,你的接收应该是这样的:
    struct bo_command_header hdr;
    recv(socket,&hdr,sizeof(hdr));
    assert(sizeof(CCSDef::TMSG_FILE)==hdr.nArg2Len);
    {
       //   or new a buff,recv & post to data-process-thread
       CCSDef::TMSG_FILE tMsgFile;
       recv(socket,&tMsgFile,sizeof(tMsgFile));
       WriteToFile(&tMsgFile);

    assert(0==hdr.nArg3Len);
      

  7.   

    make sure,,,,the whole buff is sent & received