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)
{
}
};
// 传送文件
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)
{
}
};
CCSDef::TMSG_FILE tMsgFile;
tMsgFile如何转char * 呢?
// assert(g_pBuff);另外,send和recv的代码没有贴出来
看你的代码,g_pBuff应该不是同一块内存吧(SendFile和WriteToFile中的g_pBuff),如果是同一块的话,当然出错了,因为在SendFile里,文件发送完后,把g_pBuff释放掉了
{
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 *
tMsgFile如何转char * 呢?char* pTemp = new char[sizeof(CCSDef::TMSG_FILE)];
memcpy(pTemp,&tMsgFile,sizeof(CCSDef::TMSG_FILE));
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);