想在网上传输图象,请问大家如何传输 我想使用 mfc来写个程序在客户端和服务端之间传一副图象,请问大家有什么好办法吗?图象不会太大,最多1M多。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 先压缩了再用Socket传就可以了。 传送文件: 服务器和客户极端都定义一下结构:typedef struct _SOCKET_STREAM_FILE_INFO { TCHAR szFileTitle[128]; //文件的标题名 DWORD dwFileAttributes; //文件的属性 FILETIME ftCreationTime; //文件的创建时>P FILETIME ftLastAccessTime; //文件的最后访问时>P FILETIME ftLastWriteTime; //文件的最后修改时>P DWORD nFileSizeHigh; //文件大小的高位双字 DWORD nFileSizeLow; //文件大小的低位双字 DWORD dwReserved0; //保留,为0 DWORD dwReserved1; //保留,为0} SOCKET_STREAM_FILE_INFO, * PSOCKET_STREAM_FILE_INFO; 服务器端:void CServerDlg::OnButtonLicsen() { // TODO: Add your control notification handler code here CFileDialog Dlg(TRUE); if(Dlg.DoModal()!=IDOK) return; CFile myFile; if(!myFile.Open(Dlg.GetPathName(), CFile::modeRead | CFile::typeBinary)) { AfxMessageBox("文件不存在!",MB_OK|MB_ICONERROR); return; } CSocket sockSrvr; sockSrvr.Create(800); sockSrvr.Listen(); CSocket sockRecv; sockSrvr.Accept(sockRecv); SOCKET_STREAM_FILE_INFO StreamFileInfo; WIN32_FIND_DATA FindFileData; FindClose(FindFirstFile(Dlg.GetPathName(),&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; sockRecv.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); sockRecv.Send(data, dw); dwRead+=dw; } myFile.Close(); sockRecv.Close(); AfxMessageBox("发送完毕!");}//////////////////////////////////////////////////////客户机端:void CClientDlg::OnButtonSend() { // TODO: Add your control notification handler code here AfxSocketInit(NULL); CSocket sockClient; sockClient.Create(); CString szIP; //服务器IP地址 GetDlgItemText(IDC_EDIT_IPADDRESS,szIP); //通过对话框获取服务器IP地址 if(!sockClient.Connect((LPCTSTR)szIP, 800)) { AfxMessageBox("连接到对方机器失败!"); return; } SOCKET_STREAM_FILE_INFO StreamFileInfo; sockClient.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=sockClient.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); sockClient.Close(); AfxMessageBox("接收完毕!");}显示图片:void CXXXXView::ShowPic(){ CString strPath; CFileDialog dlg(TRUE,"jpg","*.jpg", OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "JPEG文件(*.jpg)|*.jpg|GIF文件(*.gif)|*.gif||",NULL); if(dlg.DoModal()==IDOK) { strPath=dlg.GetPathName(); CDC* pDC=this->GetDC(); IStream *pStm; CFileStatus fstatus; CFile file; LONG cb; HGLOBAL hGlobal; if (file.Open(strPath,CFile::modeRead)&&file.GetStatus(strPath,fstatus)&& ((cb = fstatus.m_size) != -1)) { hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb); LPVOID pvData = NULL; if (hGlobal != NULL) { if ((pvData = GlobalLock(hGlobal)) != NULL) { file.ReadHuge(pvData, cb); GlobalUnlock(hGlobal); CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); } } file.Close(); } IPicture *pPic; //想不到,竟然使用了一个com组件 if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic))) { OLE_XSIZE_HIMETRIC hmWidth; OLE_YSIZE_HIMETRIC hmHeight; pPic->get_Width(&hmWidth); pPic->get_Height(&hmHeight); double fX,fY; fX = (double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC->GetDeviceCaps(HORZSIZE)*100.0); fY = (double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC->GetDeviceCaps(VERTSIZE)*100.0); if(FAILED(pPic->Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL))) AfxMessageBox("渲染图像失败!"); pPic->Release(); } else AfxMessageBox("从流中装载图像失败!"); GlobalFree(hGlobal); } } 如果是一般的文件传送,直接以字节流的方式传送,而如果你写的是木马之类的程序,必须先将截获的位图信息转换为DIB无关位图在发送,否则无法实现,API: setDDBtoDIB....记不清了 我有原代码。一般转换成DIB后还要压缩,这样速度可以提高很多。 请问有没有可能调用一次函数而函数实际执行了两次?线程调用。 Tesseract,有人研究么? 循环播放一个mid格式的音乐文件,在线等,马上结贴 关于多层DC的问题 如何显示取得的图标? 请问:如果把MFC exe修改成MFC(dll)大致需要多少工作量,还要注意些什么? 怎么在打开文件的同时并在view中显示内容? 类的设计问题! 怎样换行? 请高手看看这个错误是怎么回事? 怎样检查一个_RecordsetPtr变量是否有效? 请教CDC详细的用法
服务器和客户极端都定义一下结构:
typedef struct _SOCKET_STREAM_FILE_INFO { TCHAR szFileTitle[128]; //文件的标题名
DWORD dwFileAttributes; //文件的属性
FILETIME ftCreationTime; //文件的创建时>P
FILETIME ftLastAccessTime; //文件的最后访问时>P
FILETIME ftLastWriteTime; //文件的最后修改时>P
DWORD nFileSizeHigh; //文件大小的高位双字
DWORD nFileSizeLow; //文件大小的低位双字
DWORD dwReserved0; //保留,为0
DWORD dwReserved1; //保留,为0} SOCKET_STREAM_FILE_INFO, * PSOCKET_STREAM_FILE_INFO; 服务器端:
void CServerDlg::OnButtonLicsen() {
// TODO: Add your control notification handler code here
CFileDialog Dlg(TRUE);
if(Dlg.DoModal()!=IDOK)
return;
CFile myFile;
if(!myFile.Open(Dlg.GetPathName(), CFile::modeRead | CFile::typeBinary))
{
AfxMessageBox("文件不存在!",MB_OK|MB_ICONERROR);
return;
}
CSocket sockSrvr;
sockSrvr.Create(800); sockSrvr.Listen();
CSocket sockRecv;
sockSrvr.Accept(sockRecv); SOCKET_STREAM_FILE_INFO StreamFileInfo;
WIN32_FIND_DATA FindFileData; FindClose(FindFirstFile(Dlg.GetPathName(),&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; sockRecv.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);
sockRecv.Send(data, dw);
dwRead+=dw;
}
myFile.Close(); sockRecv.Close();
AfxMessageBox("发送完毕!");
}////////////////////////////////////////////////////
//客户机端:
void CClientDlg::OnButtonSend()
{
// TODO: Add your control notification handler code here
AfxSocketInit(NULL);
CSocket sockClient;
sockClient.Create(); CString szIP; //服务器IP地址
GetDlgItemText(IDC_EDIT_IPADDRESS,szIP); //通过对话框获取服务器IP地址
if(!sockClient.Connect((LPCTSTR)szIP, 800))
{
AfxMessageBox("连接到对方机器失败!");
return;
}
SOCKET_STREAM_FILE_INFO StreamFileInfo;
sockClient.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=sockClient.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);
sockClient.Close();
AfxMessageBox("接收完毕!");
}显示图片:
void CXXXXView::ShowPic()
{
CString strPath;
CFileDialog dlg(TRUE,"jpg","*.jpg",
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"JPEG文件(*.jpg)|*.jpg|GIF文件(*.gif)|*.gif||",NULL);
if(dlg.DoModal()==IDOK)
{
strPath=dlg.GetPathName();
CDC* pDC=this->GetDC();
IStream *pStm;
CFileStatus fstatus;
CFile file;
LONG cb;
HGLOBAL hGlobal;
if (file.Open(strPath,CFile::modeRead)&&file.GetStatus(strPath,fstatus)&& ((cb = fstatus.m_size) != -1))
{
hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);
LPVOID pvData = NULL;
if (hGlobal != NULL)
{
if ((pvData = GlobalLock(hGlobal)) != NULL)
{
file.ReadHuge(pvData, cb);
GlobalUnlock(hGlobal);
CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);
}
}
file.Close();
}
IPicture *pPic; //想不到,竟然使用了一个com组件
if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic)))
{
OLE_XSIZE_HIMETRIC hmWidth;
OLE_YSIZE_HIMETRIC hmHeight;
pPic->get_Width(&hmWidth);
pPic->get_Height(&hmHeight);
double fX,fY;
fX = (double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC->GetDeviceCaps(HORZSIZE)*100.0);
fY = (double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC->GetDeviceCaps(VERTSIZE)*100.0);
if(FAILED(pPic->Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL)))
AfxMessageBox("渲染图像失败!");
pPic->Release();
}
else
AfxMessageBox("从流中装载图像失败!");
GlobalFree(hGlobal);
}
}
一般转换成DIB后还要压缩,这样速度可以提高很多。