用socket控件,sendstream()发送文件,recievebuf(buf,socket->receivelength())接收,怎么知道文件大小,而给buf 开辟适当的内存

jackyjian 2005-04-16 03:02:34
用char buf[],怎么确定buf数组的大小,用len=socket->receivelength() 好像能得到这个大小,但又不能用char[len] 定义数组,矛盾啊!
还有,sendstream()如果传送一个图像文件,receivebuf()能否接收,我传送一个.txt文件,显示很正常,但一个.doc文件则显示乱码,奈何?
...全文
171 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
jackyjian 2005-04-18
  • 打赏
  • 举报
回复
多谢!!!!!!!
happyct 2005-04-18
  • 打赏
  • 举报
回复

Client.cpp

//---------------------------------------------------------------------------
// CLIENT端
//
// 贾佳,jiasys@21cn.com
//---------------------------------------------------------------------------

#include <vcl.h>
#include <winsock.h>
#define BUFFSIZE 1024
#pragma hdrstop

#include "Client.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

WSADATA wsa;
SOCKET sck;
SOCKADDR_IN tto;
hostent *host;
fd_set FdRead;
int port=926,ret,i;
DWORD dwRead;


//---------------------------------------------------------------------------
// ReadClient
//
// 接收文件数据线程,判断建立文件关键字,每次将实际读到的数据写入文件。
//
//---------------------------------------------------------------------------

DWORD WINAPI ReadClient(LPVOID lParam)
{
HANDLE hFile;
DWORD dwWrite,dwFileSize;
TCHAR szFileName[MAX_PATH];
TCHAR szBuff[BUFFSIZE];

FD_ZERO(&FdRead);
FD_SET(sck,&FdRead);

while(TRUE)
{
ret=select(0,&FdRead,NULL,NULL,NULL);
if(ret==SOCKET_ERROR)
{
closesocket(sck);
return FALSE;
}
else if(FD_ISSET(sck,&FdRead))
{
ZeroMemory(szBuff,sizeof(szBuff));
if((dwFileSize=recv(sck,szBuff,BUFFSIZE,0))==SOCKET_ERROR)
{
closesocket(sck);
CloseHandle(hFile);
return FALSE;
}
else if((strncmp(szBuff,"DOWNFILE_",lstrlen("DOWNFILE_")))==0)
{
wsprintf(szFileName,"c:\\%s",szBuff);
hFile=CreateFile(szFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,
NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL|
FILE_ATTRIBUTE_ARCHIVE,(HANDLE)NULL);

if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"Cli Open File Error",NULL,MB_OK);
return FALSE;
}
ZeroMemory(szBuff,sizeof(szBuff));
}
else
WriteFile(hFile,szBuff,dwFileSize,&dwWrite,NULL);
}
}
return TRUE;
}

//---------------------------------------------------------------------------
// WriteClient
//
// 发送文件数据线程,每次预读1K数据,根据实际读取发送,直到读取数据小于1K
//
//---------------------------------------------------------------------------

DWORD WINAPI WriteClient(LPVOID szFileName)
{
HANDLE hFile;
DWORD dwRead,dwNdx;
BOOL bRet;
TCHAR szFileBuff[BUFFSIZE],szSend[MAX_PATH];

wsprintf(szSend,"UPFILE_%s",ExtractFileName((LPCTSTR)szFileName).c_str());
send(sck,szSend,lstrlen(szSend),0);
hFile=CreateFile((LPCTSTR)szFileName,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|
FILE_ATTRIBUTE_ARCHIVE,(HANDLE)NULL);

if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"Open File Error",NULL,MB_OK);
ExitProcess(0);
}

do
{
bRet=ReadFile(hFile,szFileBuff,BUFFSIZE,&dwRead,NULL);
if(bRet==FALSE)
{
MessageBox(NULL,"Read Buf ERROR!",NULL,MB_OK);
break;
}
else if(dwRead==0)
{
MessageBox(NULL,"File EOF!",NULL,MB_OK);
break;
}
else
{
send(sck,szFileBuff,dwRead,0);
}
}while(dwRead==BUFFSIZE);

CloseHandle(hFile);
return TRUE;
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE hThread;
DWORD dwTid;

WSAStartup(MAKEWORD(1,1),&wsa);
sck=socket(AF_INET,SOCK_STREAM,0);

if(sck==INVALID_SOCKET)
{
ShowMessage("Could not create a sock");
ExitProcess(0);
}

else
{
host=gethostbyname(Edit1->Text.c_str());
tto.sin_family=AF_INET;
tto.sin_port=htons(port);
CopyMemory(&tto.sin_addr,host->h_addr,host->h_length);
if((connect(sck,(struct sockaddr FAR *)&tto,sizeof(tto))==SOCKET_ERROR))
{
ShowMessage("connect error!");
closesocket(sck);
}

else
{
hThread=CreateThread(NULL,0,ReadClient,(LPVOID)0,0,&dwTid);
CloseHandle(hThread);
}
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
HANDLE hThread;
DWORD dwTid;

if(OpenDialog1->Execute())
{
hThread=CreateThread(NULL,0,WriteClient,(LPVOID)OpenDialog1->FileName.c_str(),0,&dwTid);
CloseHandle(hThread);
}
}
//---------------------------------------------------------------------------
happyct 2005-04-18
  • 打赏
  • 举报
回复
Server.cpp

//---------------------------------------------------------------------------
// SERVER端
//
// 贾佳,jiasys@21cn.com
//---------------------------------------------------------------------------

#include <vcl.h>
#include <winsock.h>
#define BUFFSIZE 1024
#pragma hdrstop

#include "Server.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

WSADATA wsaData;
SOCKET sck,sc;
SOCKADDR_IN to,client;
BOOL flag=TRUE;
int iAddrSize,ret,ret_no,i=0;
TCHAR szBuf[BUFFSIZE];
fd_set FdRead;

//---------------------------------------------------------------------------
// ReadClient
//
// 接收文件数据线程,判断建立文件关键字,每次将实际读到的数据写入文件。
//
//---------------------------------------------------------------------------

DWORD WINAPI ReadClient(LPVOID lPort)
{
HANDLE hFile=NULL;
DWORD dwWrite,dwFileSize;
TCHAR szFileName[MAX_PATH];

FD_ZERO(&FdRead);
FD_SET(sck,&FdRead);

while(TRUE)
{
ret_no=select(0,&FdRead,NULL,NULL,NULL);
if(ret_no==SOCKET_ERROR)
{
closesocket(sck);
return FALSE;
}

if(FD_ISSET(sck,&FdRead))
{
iAddrSize=sizeof(client);
sc=accept(sck,(SOCKADDR *)&client,&iAddrSize);
if(sc==INVALID_SOCKET)
{
MessageBox(NULL,"accept error",NULL,MB_OK);
closesocket(sc);
WSACleanup();
}
getpeername(sck,(SOCKADDR *)&client,&iAddrSize);
ShowMessage(inet_ntoa(client.sin_addr));
FD_SET(sc,&FdRead);
}

if(FD_ISSET(sc,&FdRead))
{
ZeroMemory(szBuf,sizeof(szBuf));
if((dwFileSize=recv(sc,szBuf,BUFFSIZE,0))==SOCKET_ERROR)
{
closesocket(sc);
CloseHandle(hFile);
return FALSE;
}
else if((strncmp(szBuf,"UPFILE_",lstrlen("UPFILE_")))==0)
{
wsprintf(szFileName,"c:\\%s",szBuf);
hFile=CreateFile(szFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,
NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL|
FILE_ATTRIBUTE_ARCHIVE,(HANDLE)NULL);

if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"Server Open File Error",NULL,MB_OK);
return FALSE;
}
ZeroMemory(szBuf,sizeof(szBuf));
}
else
WriteFile(hFile,szBuf,dwFileSize,&dwWrite,NULL);
}
}
CloseHandle(hFile);
return TRUE;
}

//---------------------------------------------------------------------------
// WriteClient
//
// 发送文件数据线程,每次预读1K数据,根据实际读取发送,直到读取数据小于1K
//
//---------------------------------------------------------------------------

DWORD WINAPI WriteClient(LPVOID szFileName)
{

HANDLE hFile;
DWORD dwRead,dwNdx;
BOOL bRet;
TCHAR szFileBuff[BUFFSIZE],szSend[MAX_PATH];

wsprintf(szSend,"DOWNFILE_%s",ExtractFileName((LPCTSTR)szFileName).c_str());
send(sc,szSend,lstrlen(szSend),0);
hFile=CreateFile((LPCTSTR)szFileName,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|
FILE_ATTRIBUTE_ARCHIVE,(HANDLE)NULL);

if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"Open File Error",NULL,MB_OK);
ExitProcess(0);
}

do
{
bRet=ReadFile(hFile,szFileBuff,BUFFSIZE,&dwRead,NULL);
if(bRet==FALSE)
{
MessageBox(NULL,"Read Buf ERROR!",NULL,MB_OK);
break;
}
else if(dwRead==0)
{
MessageBox(NULL,"File EOF!",NULL,MB_OK);
break;
}
else
{
send(sc,szFileBuff,dwRead,0);
}
}while(dwRead==BUFFSIZE);

CloseHandle(hFile);
return TRUE;
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE hThread;
DWORD dwTid;

if(OpenDialog1->Execute())
{
hThread=CreateThread(NULL,0,WriteClient,(LPVOID)OpenDialog1->FileName.c_str(),0,&dwTid);
CloseHandle(hThread);
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
HANDLE hThread;
DWORD dwTid;

if(WSAStartup(MAKEWORD(1,1),&wsaData)!=NULL)
{
ShowMessage("初始化WINSOCK错误");
WSACleanup();
}

if((sck=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)
{
ShowMessage("SOCKET错误");
closesocket(sck);
WSACleanup();
}

to.sin_family=AF_INET;
to.sin_port=htons(926);
to.sin_addr.s_addr=htonl(INADDR_ANY);

if(setsockopt(sck,SOL_SOCKET,SO_REUSEADDR,(LPSTR)&flag,sizeof(flag))==SOCKET_ERROR)
{
ShowMessage("setsockopt error!");
closesocket(sck);
}


if(bind(sck,(struct sockaddr *)&to,sizeof(to))==SOCKET_ERROR)
{
ShowMessage("Could not bind");
closesocket(sck);
}

else
{
listen(sck,1);
hThread=CreateThread(NULL,0,ReadClient,(LPVOID)0,0,&dwTid);
CloseHandle(hThread);
}
}
//---------------------------------------------------------------------------
happyct 2005-04-18
  • 打赏
  • 举报
回复
这是每个新人都犯的错误(我也是新人啊)

发送一个文件,你不要想到用SendStream或者SendBuf一次给发完。。。。这两个函数没有这么大的能力,还需要你自己处理

你可以从一个文件中每次读1000个字节,发送,接收,再发送接收,每次1000,(不够1000的话那铁定是文件已经发完了)

给你一个发送接收的例子:
jackyjian 2005-04-18
  • 打赏
  • 举报
回复
我的意思是ServerSocket发送一个流文件用sendstream():
if(OpenDialog1->Execute())
{
TFileStream *file=new TFileStream(OpenDialog1->FileName,fmOpenRead);
ServerSocket1->Socket->Connections[0]->SendStream(file)
ClientSocket接收并存入临时文件:

void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
char buf[204800]; //?????buf 的大小随接收文件的不同而不同,需动态数组
int len=Socket->ReceiveLength();
Socket->ReceiveBuf(buf,Socket->ReceiveLength());
FILE *fp;
String file=ExtractFilePath(Application->ExeName);
file=file+"\\temp.doc";//??????怎么确定接收文件的格式,客户可以发送任何扩展名的文件啊
fp=fopen(file.c_str(),"w");
fwrite(buf,1,len,fp);
}

不知这样表达清不清楚? 如果还不明白,关于发送和接收文件,也可以提供更好的方法

icwin 2005-04-17
  • 打赏
  • 举报
回复
楼主的意思,不明白,
你应该知道你发送的每个buf的尺寸阿?
为什么需要文件的大小了

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧