我想使用 mfc来写个程序在客户端和服务端之间传一副图象,请问大家有什么好办法吗?图象不会太大,最多1M多。

解决方案 »

  1.   

    先压缩了再用Socket传就可以了。
      

  2.   

    传送文件:
        服务器和客户极端都定义一下结构:
    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);
    }

    }
      

  3.   

    如果是一般的文件传送,直接以字节流的方式传送,而如果你写的是木马之类的程序,必须先将截获的位图信息转换为DIB无关位图在发送,否则无法实现,API:  setDDBtoDIB....记不清了
      

  4.   

    我有原代码。
    一般转换成DIB后还要压缩,这样速度可以提高很多。