psycheqiqi 发表于 2009-9-16 09:22:30

传文件的问题

我写的传文件实现了传输文本文件的功能,但如果我想传图像或者其它格式的文件的话怎么设置
发送的程序:
CString str;
sendFile.Abort();
sendFile.Open(sendFileName,CFile::modeRead | CFile::typeBinary );
sendFileLen = sendFile.GetLength();
if(sendFileLen<MAX_DATA_BUFF)
MessageBox("OK");
else
{
MessageBox("Too Large");
return ;
}
BYTE* membuf= (BYTE*)LocalAlloc(LMEM_FIXED,sendFileLen);
memset(membuf,0,sendFileLen);
    sendFile.ReadHuge(membuf,sendFileLen);
sendFile.Close();
str.Format("%d",sendFileLen);
    pc->peer().send(membuf,sendFileLen);
LocalFree(membuf);
接受的程序:
if (dlg->MessageBox("是否接收数据?","提示",MB_YESNO)==IDYES)
    {
   CString returnPath;
   TCHAR szPath;
   BROWSEINFO bInfo;
   bInfo.hwndOwner = NULL;
   bInfo.pidlRoot= NULL;
   bInfo.pszDisplayName = szPath;
   bInfo.lpszTitle ="请选择目的路径";
   bInfo.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS|BIF_BROWSEFORCOMPUTER;
   bInfo.lParam=NULL;
   bInfo.lpfn=NULL;
   LPITEMIDLIST lpList =SHBrowseForFolder(&bInfo);
   SHGetPathFromIDList(lpList,szPath);

      CString filePath = szPath ;
   filePath += "\\";
   filePath += recvFileName;
         dlg->MessageBox(filePath);
      //往文件里写内容
       //保存文件对话框的问题
      if (file_connector.connect(file,
   ACE_FILE_Addr (filePath),
    0,
    ACE_Addr::sap_any,
    0,
    O_RDWR|O_CREAT|O_APPEND|O_BINARY
    ) == -1)
   {
    printf("error");
   }
   int len=recv_cnt;
   if (file.send (buffer, len) != len)
    ACE_ERROR_RETURN ((LM_ERROR,
    "%p\n",
    "send"),
    1);
   
   if (file.close () == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
    "%p\n",
    "close"),
    1);
   dlg->MessageBox("传送完毕");
    }
return 0;
}
    LocalFree(buffer);
return 0;

winston 发表于 2009-9-16 10:04:53

注意抽象的概念 - 网络不关心传输的是什么,至于你怎么理解内容,是你的事情。
明白了么?完全一样啊。

psycheqiqi 发表于 2009-9-16 10:30:08

回复 #2 winston 的帖子

但是上面的程序实现了传文本的功能,传图片或者别的内容都少了很多,而且乱码

psycheqiqi 发表于 2009-9-16 11:08:50

回复 #3 psycheqiqi 的帖子

我调试了下,发送是正确的,不如发送了160000个字节,但接收到的只有10220的字节?

psycheqiqi 发表于 2009-9-16 11:40:37

回复 #4 psycheqiqi 的帖子

还是上面的程序,
接受端:
const size_t INPUT_SIZE =1000*1000;
BYTEbuffer;
DWORD recv_cnt,send_cnt;

const int MAXHOSTNAMELEN=32;
ACE_TCHAR peer_name;
        ACE_INET_Addr peer_addr;
       

        CString str;

        CAceTestDlg *dlg=(CAceTestDlg*)AfxGetApp()->GetMainWnd();

       this->sock_.get_remote_addr(peer_addr);
   peer_addr.addr_to_string(peer_name,MAXHOSTNAMELEN);
       recv_cnt = this->sock_.recv(buffer,sizeof(buffer));

recv接受到的数据为什么会少很多???

psycheqiqi 发表于 2009-9-16 11:41:16

回复 #4 psycheqiqi 的帖子

还是上面的程序,
接受端:
const size_t INPUT_SIZE =1000*1000;
BYTEbuffer;
DWORD recv_cnt,send_cnt;

const int MAXHOSTNAMELEN=32;
ACE_TCHAR peer_name;
        ACE_INET_Addr peer_addr;
       

        CString str;

        CAceTestDlg *dlg=(CAceTestDlg*)AfxGetApp()->GetMainWnd();

       this->sock_.get_remote_addr(peer_addr);
   peer_addr.addr_to_string(peer_name,MAXHOSTNAMELEN);
       recv_cnt = this->sock_.recv(buffer,sizeof(buffer));

recv接受到的数据为什么会少很多???

modern 发表于 2009-9-16 12:31:29

楼主一下子发160000字节?
socket缓冲区哪有那么大呀!
不丢才怪嘞

psycheqiqi 发表于 2009-9-16 12:37:05

回复 #7 modern 的帖子

有什么比较简单的方法解决吗?

psycheqiqi 发表于 2009-9-16 16:05:17

回复 #7 modern 的帖子

我试了下,最多一次传8192个字节。我想传更多怎么设置?
能修改缓冲区的大小吗?或者其它方法?

psycheqiqi 发表于 2009-9-16 16:51:15

回复 #9 psycheqiqi 的帖子

现在能传过去了,但是有乱码
发送端:
void CAceClientDlg::OnFileSend()
{
        // TODO: Add your control notification handler code here

        CString str;
        sendFile.Abort();
                sendFile.Open(sendFileName,CFile::modeRead );
        sendFileLen = sendFile.GetLength();
        if(sendFileLen<MAX_DATA_BUFF)
                MessageBox("OK");
        else
        {
                MessageBox("Too Large");
                return ;
        }

        int size=8191;
                int i=0;
        iovec send;
        while(sendFileLen>size)
        {
               
        char* membuf= (char*)LocalAlloc(LMEM_FIXED,size+1);
        memset(membuf,0,size+1);
        sendFile.ReadHuge(membuf,size);
        membuf='%';
        send.iov_base = membuf;
        send.iov_len = size+1;
        i++;
        sendFileLen -= size;
        LocalFree(membuf);
        }
        char* membuf= (char*)LocalAlloc(LMEM_FIXED,sendFileLen+1);
        memset(membuf,0,sendFileLen+1);
        sendFile.ReadHuge(membuf,sendFileLen);
        membuf='%';
        send.iov_base = membuf;
        send.iov_len = sendFileLen+1;
        i++;
        pc->peer().send(send,i);
        LocalFree(membuf);
}
接受端:
        const size_t INPUT_SIZE =1000*1000;//INPUT_SIZE的值可以修改,具体多大不会出错待定
//        charbuffer;
    char *buffer;

        DWORD recv_cnt,send_cnt;
        iovec response;


        const int MAXHOSTNAMELEN=32;
        ACE_TCHAR peer_name;
        ACE_INET_Addr peer_addr;
       

        CString str;

        CAceTestDlg *dlg=(CAceTestDlg*)AfxGetApp()->GetMainWnd();

       this->sock_.get_remote_addr(peer_addr);
   peer_addr.addr_to_string(peer_name,MAXHOSTNAMELEN);
   recv_cnt = this->sock_.recvv(&response);
       buffer = response.iov_base ;
//       recv_cnt = this->sock_.recv(buffer,sizeof(buffer));
        if(recv_cnt <=0 )
        {
                ACE_DEBUG((LM_DEBUG,
                        ACE_TEXT("%s Connection closed\n"),peer_name));
                num--;
                str.Format("%s Connection closed\n",peer_name);
                m_lbx->AddString(str);
                return -1;
        }

if( buffer == '@')
{        //文字信息
          buffer = '\0';
          str.Format("%s send : ",peer_name);
          str += buffer;
          m_lbx->AddString(str);
          return 0;
}
if( buffer == '$')
{        //文件名
          buffer = '\0';
       

           recvFileName = buffer;
           dlg->MessageBox(recvFileName);
          return 0;

}
if(buffer =='%')
{ //文件内容
           buffer = '\0';
           str.Format("%d",recv_cnt-1);
          dlg->MessageBox(str);

           if (dlg->MessageBox("是否接收数据?","提示",MB_YESNO)==IDYES)
           {
                  /* CString returnPath;
                   TCHAR szPath;
                   BROWSEINFO bInfo;
                   bInfo.hwndOwner = NULL;
                   bInfo.pidlRoot= NULL;
                   bInfo.pszDisplayName = szPath;
                   bInfo.lpszTitle ="请选择目的路径";
                   bInfo.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS|BIF_BROWSEFORCOMPUTER;
                   bInfo.lParam=NULL;
                   bInfo.lpfn=NULL;

                   LPITEMIDLIST lpList =SHBrowseForFolder(&bInfo);
                   SHGetPathFromIDList(lpList,szPath);
               
         CString filePath = szPath ;
               filePath += "\\";
//用来区分哪个客户端发来的文件,把其IP地址放在文件名的前一级目录。
//               filePath += peer_name
//                  filePath += "\\";
               filePath += recvFileName;
               */
                  CString filePath = "E://" + recvFileName;
         dlg->MessageBox(filePath);
             //往文件里写内容
              //保存文件对话框的问题
             if (file_connector.connect(file,
               ACE_FILE_Addr (filePath),
                  0,
                  ACE_Addr::sap_any,
                  0,
                  O_RDWR|O_CREAT|O_APPEND
                  ) == -1)
          {
                  printf("error");
          }
          int len=recv_cnt-1;
          if (file.send (buffer, len) != len)
                  ACE_ERROR_RETURN ((LM_ERROR,
                  "%p\n",
                  "send"),
                  1);
//所传文件的信息          
          
          if (file.close () == -1)
                  ACE_ERROR_RETURN ((LM_ERROR,
                  "%p\n",
                  "close"),
                  1);
          dlg->MessageBox("传送完毕");

           }
                return 0;
}
    LocalFree(buffer);
        return 0;


}
页: [1] 2
查看完整版本: 传文件的问题