我用CAsyncSocket写了一个服务器端和客户端的程序,想让客户端把文件传输到服务器端。这个程序是异步非阻塞的。
客户端的OnSend(int nErrorCode)函数里有个while循环,如果发送的字节数小于文件长度就一直ReadFile()并Send()
服务器端的OnReceive(int nErrorCode)函数里也有个while循环,如果写进文件中的字节数小于文件长度就一直Receive()并WriteFile()。
我用断点调试,一边发一边收没什么问题,但是让两边程序都运行,客户端发送文件,总是发不完全,比如600K的文件到服务器端只有60K。小点的文件就没有问题,比如3K左右的txt文件能完好发送。问题出在哪儿?是不是收发速度不协调导致的?
客户端的OnSend是通过一个FD_WRITE来调用的。
本人超级菜鸟啊。PS:本人没有分,好像只有5分了希望有人能慷慨相助
客户端的OnSend(int nErrorCode)函数里有个while循环,如果发送的字节数小于文件长度就一直ReadFile()并Send()
服务器端的OnReceive(int nErrorCode)函数里也有个while循环,如果写进文件中的字节数小于文件长度就一直Receive()并WriteFile()。
我用断点调试,一边发一边收没什么问题,但是让两边程序都运行,客户端发送文件,总是发不完全,比如600K的文件到服务器端只有60K。小点的文件就没有问题,比如3K左右的txt文件能完好发送。问题出在哪儿?是不是收发速度不协调导致的?
客户端的OnSend是通过一个FD_WRITE来调用的。
本人超级菜鸟啊。PS:本人没有分,好像只有5分了希望有人能慷慨相助
要是让我写客户端的文件发送到服务器,我会采用阻塞的方式,单独地开通一条线程用来处理文件的发送,我曾做试过,用的是TCP。发送几百M,甚至几G的数据都不会出错
{
// TODO: Add your specialized code here and/or call the base class
if(nErrorCode==0)
{
DWORD dwRead=0; //每次从文件中读出的字节数
DWORD ret=0; //每次Send字节数
DWORD idx=0; //Send的控制游标
char * data=new char[2048]; //数据缓冲区
if(dwBytesRead==0) //dwBytesRead为总Send字节数
{
_CreateFile(); //创建要发送文件的句柄
SendFileDataStruct(); //把文件信息先传过去
}
if(hFile==INVALID_HANDLE_VALUE)
{
return;
}
while(dwBytesRead<m_FileLength)
{
memset(data,0,2048);
idx=0;
if(false==ReadFile(hFile,data,2048,&dwRead,NULL)) //...
{
CloseHandle(hFile);
return;
}
while(dwRead>0)
{
ret=Send(data+idx,dwRead);
if(ret==SOCKET_ERROR)
break;
dwRead-=ret;
idx+=ret;
dwBytesRead+=ret;
}
}
if(dwBytesRead==m_FileLength)
{
delete [] data;
CloseHandle(hFile);
}
}
CAsyncSocket::OnSend(nErrorCode);
}
{
// TODO: Add your specialized code here and/or call the base class
if(nErrorCode==0)
{
DWORD dwWrite=0;
DWORD ret=0;
char * data=new char[4096];
if(dwBytesWrite==0)
{
AcceptFileDataStruct();
_CreateFile();
}
if(hFile==INVALID_HANDLE_VALUE)
{
return;
}
while(dwBytesWrite<Stream_File_Info.nFileSizeLow)
{
memset(data,0,4096);
dwWrite=0;
DWORD nLeft=2048;
DWORD idx=0;
if((Stream_File_Info.nFileSizeLow-dwBytesWrite)>=2048)
while(nLeft>0)
{
ret=Receive(data+idx,nLeft);
if(ret==SOCKET_ERROR)
break;
idx+=ret;
nLeft-=ret;
}
else
ret=Receive(data,Stream_File_Info.nFileSizeLow-dwBytesWrite);
if(ret>0)
{ while(dwWrite<ret)
{
if(false==WriteFile(hFile,data+dwWrite,ret-dwWrite,&dwWrite,NULL))
{
CloseHandle(hFile); //!!!!!!!!!!!!!!!!!!!!!!
return;
}
}
dwBytesWrite+=ret;
}
else
break;
}
if(dwBytesWrite==Stream_File_Info.nFileSizeLow)
{
delete [] data;
SetFileTime((HANDLE)hFile,
&Stream_File_Info.ftCreationTime,
&Stream_File_Info.ftLastAccessTime,
&Stream_File_Info.ftLastWriteTime);
SetFileAttributes(Stream_File_Info.szFileTitle,
Stream_File_Info.dwFileAttributes);
CloseHandle(hFile);
}
}
CAsyncSocket::OnReceive(nErrorCode);
}
发送端发送完一次数据后,等待对方接收数据并回复一个响应后再继续发下一次数据。也就是说增加一个
确认机制,接收端在接收到数据后给发送端一个确认响应。这样就不会出现逆说的收发不一致的现象。