传文件的问题
我写的传文件实现了传输文本文件的功能,但如果我想传图像或者其它格式的文件的话怎么设置发送的程序:
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; 注意抽象的概念 - 网络不关心传输的是什么,至于你怎么理解内容,是你的事情。
明白了么?完全一样啊。
回复 #2 winston 的帖子
但是上面的程序实现了传文本的功能,传图片或者别的内容都少了很多,而且乱码回复 #3 psycheqiqi 的帖子
我调试了下,发送是正确的,不如发送了160000个字节,但接收到的只有10220的字节?回复 #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接受到的数据为什么会少很多???
回复 #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接受到的数据为什么会少很多??? 楼主一下子发160000字节?
socket缓冲区哪有那么大呀!
不丢才怪嘞
回复 #7 modern 的帖子
有什么比较简单的方法解决吗?回复 #7 modern 的帖子
我试了下,最多一次传8192个字节。我想传更多怎么设置?能修改缓冲区的大小吗?或者其它方法?
回复 #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