利用socket进行文件传输的问题 我前段时间做了个文件传输的程序,有点心得。首先想问你是怎么recv的?用同步接收还是异步接收? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我有啊,发送: if(!myFile.Open("temp.bmp", CFile::modeRead | CFile::typeBinary)) { AfxMessageBox("文件不存在!",MB_OK|MB_ICONERROR); return; } SOCKET_STREAM_FILE_INFO StreamFileInfo; WIN32_FIND_DATA FindFileData; FindClose(FindFirstFile("temp.bmp",&FindFileData)); memset(&StreamFileInfo,0,sizeof(SOCKET_STREAM_FILE_INFO)); strcpy(StreamFileInfo.szFileTitle,myFile.GetFileTitle()); StreamFileInfo.dwFileAttributes = FindFileData.dwFileAttributes; StreamFileInfo.ftCreationTime = FindFileData.ftCreationTime; StreamFileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime; StreamFileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime; StreamFileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh; StreamFileInfo.nFileSizeLow = FindFileData.nFileSizeLow; for(int i=0;i<server.AcceptNO;i++) if(clien[i].Connected) pSocket[i]->Send(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO)); UINT dwRead=0; while(dwRead<StreamFileInfo.nFileSizeLow) { byte* data = new byte[1024]; UINT dw=myFile.Read(data, 1024); for(int i=0;i<server.AcceptNO;i++) if(clien[i].Connected) pSocket[i]->Send(data, dw); dwRead+=dw; } myFile.Close();接受: SOCKET_STREAM_FILE_INFO StreamFileInfo; client->Receive(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO)); CFile destFile(StreamFileInfo.szFileTitle, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); UINT dwRead = 0; while(dwRead<StreamFileInfo.nFileSizeLow) { byte* data = new byte[1024]; memset(data,0,1024); UINT dw=client->Receive(data, 1024); destFile.Write(data, dw); dwRead+=dw; } SetFileTime((HANDLE)destFile.m_hFile,&StreamFileInfo.ftCreationTime, &StreamFileInfo.ftLastAccessTime,&StreamFileInfo.ftLastWriteTime); destFile.Close(); SetFileAttributes(StreamFileInfo.szFileTitle,StreamFileInfo.dwFileAttributes); 传输文件我的办法是这样:0.接受端先得知文件名称与大小,还有数据包大小,得到这个文件的数据包数量。1.开辟两个线程,一个接收,一个发送。2.两者建立TCP连接,完毕后接收端使用recv( )来接受数据(堵塞状态)3.发送端开始发送自定义大小数据包,发送完毕后马上使用recv( )来接收发送标记(也是堵塞状态)4.这时接收端开始获得数据,利用while(1){recv( );}通过一次或多次接收把当前数据包接受完整后send给发送端一个继续标记(当然也可以是放弃标记),最后再recv( )等待下一个数据包.5.当发送端recv到接收端给出的继续标记后,则继续发送下一个数据包,然后在recv等待继续标记。6.循环执行步骤3-57.当到传输最后一个数据包时,两段都要注意这个数据包的有效大小,正确读写文件。8.当最后一个数据包被接收端完整接收后,发送一个"接收完毕"的标志给发送端,这标志着传输的顺利完成。9.中断TCP连接。(PS:发送过程中也可以刷新相应的UI,例如发送进度对话框)希望大家来指点交流。 pSocket[i]->Send(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO));client->Receive(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO));文件信息数据一次Send或Receive不一定可以保证全部发出来或收到。还有,是不是程序的字节对齐不一致,最好全改成1字节对齐编译方式 2 moony_blue(发呆的深蓝) :我也做了一个,效果不够理想,你能给我一份你的代码吗?谢谢。 高难度的hook问题——进程创建时的side-by-side处理 WIN7 XP区别??????????? 网络和多线程资源占用问题 控件的显示与隐藏 动态 加载 资源 问题 ATL的COM组件DLL,生成一个主窗口里面再创建一个Activex OCX,为什么会创建失败?求教高手! 如何获取可执行文件本身的大小或hash值? 如何使我应用程序窗口总处在顶部?类似于Win2k的任务管理器? 透明窗体的刷新问题 在C++中修改Windows2000用户的密码?大虾来看!! ActiveX ATL高手的请进来 应用程序没有标题栏,怎么进行虚框拖动
if(!myFile.Open("temp.bmp", CFile::modeRead | CFile::typeBinary))
{
AfxMessageBox("文件不存在!",MB_OK|MB_ICONERROR);
return;
}
SOCKET_STREAM_FILE_INFO StreamFileInfo;
WIN32_FIND_DATA FindFileData; FindClose(FindFirstFile("temp.bmp",&FindFileData));
memset(&StreamFileInfo,0,sizeof(SOCKET_STREAM_FILE_INFO));
strcpy(StreamFileInfo.szFileTitle,myFile.GetFileTitle()); StreamFileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
StreamFileInfo.ftCreationTime = FindFileData.ftCreationTime;
StreamFileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
StreamFileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
StreamFileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
StreamFileInfo.nFileSizeLow = FindFileData.nFileSizeLow; for(int i=0;i<server.AcceptNO;i++)
if(clien[i].Connected)
pSocket[i]->Send(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO)); UINT dwRead=0;
while(dwRead<StreamFileInfo.nFileSizeLow)
{
byte* data = new byte[1024];
UINT dw=myFile.Read(data, 1024);
for(int i=0;i<server.AcceptNO;i++)
if(clien[i].Connected)
pSocket[i]->Send(data, dw);
dwRead+=dw;
}
myFile.Close();接受:
SOCKET_STREAM_FILE_INFO StreamFileInfo;
client->Receive(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO)); CFile destFile(StreamFileInfo.szFileTitle, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary); UINT dwRead = 0;
while(dwRead<StreamFileInfo.nFileSizeLow)
{
byte* data = new byte[1024];
memset(data,0,1024); UINT dw=client->Receive(data, 1024);
destFile.Write(data, dw); dwRead+=dw;
} SetFileTime((HANDLE)destFile.m_hFile,&StreamFileInfo.ftCreationTime,
&StreamFileInfo.ftLastAccessTime,&StreamFileInfo.ftLastWriteTime);
destFile.Close();
SetFileAttributes(StreamFileInfo.szFileTitle,StreamFileInfo.dwFileAttributes);
1.开辟两个线程,一个接收,一个发送。
2.两者建立TCP连接,完毕后接收端使用recv( )来接受数据(堵塞状态)
3.发送端开始发送自定义大小数据包,发送完毕后马上使用recv( )来接收发送标记(也是堵塞状态)
4.这时接收端开始获得数据,利用while(1){recv( );}通过一次或多次接收把当前数据包接受完整后send给发送端一个继续标记(当然也可以是放弃标记),最后再recv( )等待下一个数据包.
5.当发送端recv到接收端给出的继续标记后,则继续发送下一个数据包,然后在recv等待继续标记。
6.循环执行步骤3-5
7.当到传输最后一个数据包时,两段都要注意这个数据包的有效大小,正确读写文件。
8.当最后一个数据包被接收端完整接收后,发送一个"接收完毕"的标志给发送端,这标志着传输的顺利完成。
9.中断TCP连接。(PS:发送过程中也可以刷新相应的UI,例如发送进度对话框)希望大家来指点交流。
client->Receive(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO));
文件信息数据一次Send或Receive不一定可以保证全部发出来或收到。还有,是不是程序的字节对齐不一致,最好全改成1字节对齐编译方式
我也做了一个,效果不够理想,你能给我一份你的代码吗?
谢谢。