发送与接收文件的问题,急急急!(附上源码)(50分)

S

samen

Unregistered / Unconfirmed
GUEST, unregistred user!
IDTCPSERVER IDTCPCLIENT如何发送和接收???
执行下面代码,提示SOCKET 10054错误。
procedure TForm1.SpeedButton1Click(Sender: TObject);
const blocklen=4096;
var
flen:integer;
blocknum:integer;
remainlen:integer;
i:integer;
begin
idtcpclient1.Connect;
assignfile(Ftrans,'c:/a.txt');
reset(ftrans);
flen:=filesize(ftrans);
blocknum:=flen div blocklen;
remainlen:=flen mod blocklen;

for i:=0 to blocknum-1 do //文件分块的字节块发送
begin
blockread(ftrans,blockbuf[0],blocklen);
idtcpclient1.WriteBuffer(blockbuf,blocklen,false);
end;
if (remainlen>0) then //文件剩余的字节数发送
begin
blockread(ftrans,blockbuf[0],remainlen);
idtcpclient1.WriteBuffer(blockbuf,remainlen,false);
end;
closefile(ftrans);
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
Ftrans:file of byte;
blockbuf:ARRAY[0..4096-1] of byte;
recelen:integer;
begin
assignfile(Ftrans,'c:/b.txt');
recelen:=AThread.Connection.RecvBufferSize;
AThread.Connection.ReadBuffer(blockbuf,recelen);
rewrite(ftrans);
while (recelen>0) do
begin
blockwrite(ftrans,blockbuf[0],recelen);
recelen:=AThread.Connection.RecvBufferSize;
AThread.Connection.ReadBuffer(blockbuf,recelen);
end;
closefile(ftrans);
end;
 
发送部分有问题,要检查发送函数返回的实际发送数值,
10054的错误你查了WINSOCDK帮助没?
 
请修改一下上面的代码。
 
flen:=filesize(ftrans);
blocknum:=flen div blocklen;
remainlen:=flen mod blocklen;

for i:=0 to blocknum-1 do //文件分块的字节块发送
begin
blockread(ftrans,blockbuf[0],blocklen);
idtcpclient1.WriteBuffer(blockbuf,blocklen,false);
end;
if (remainlen>0) then //文件剩余的字节数发送
begin
blockread(ftrans,blockbuf[0],remainlen);
idtcpclient1.WriteBuffer(blockbuf,remainlen,false);
end;
closefile(ftrans);
这个循环要改掉,
 
接受部分
procedure TForm1.ClientSocket2Read(Sender: TObject;
Socket: TCustomWinSocket);
var len:integer;
temp:string;
begin
if stStatue=stgetFile then
begin
Len:=Socket.ReceiveLength;
Temp:=Socket.ReceiveText;
filem.Write(PChar(Temp)^,len); //filem是一个文件流
inc(allLen,len);
if allLen=getfilesize then //allLen是文件长度,你先传送过来
ShowMessage('文件接受完毕!');
end;

发送部分
const
MAX_LEN=2048;

var
iSen:integer; //iSen发送出去的长度
iSize:integer; //文件长度 最好是全局变量
buf:array[1..MAXLEN]of char;
senlen:integer; //每次应该发送的长度
ret:integer; //实际发送的文件长度
filen:TFileStream; //最好是全局变量

iSen:=0;
while iSen<iSize do
begin
FillChar(buf,MAX_LEN,0);
if iSize-iSen>MAX_LEN then senlen:=MAX_LEN
else senLen:=iSize-iSen;
filen.Position:=iSen;
filen.Read(buf,senLen);
ret:=ClientSocket1.Socket.SendBuf(buf,senLen);
inc(iSen,ret);
end;
 
哪里的循环?
 
用cliensocket serversocket完全可以的,但现在是用INDY控件呀
 
flen:=filesize(ftrans);
blocknum:=flen div blocklen;
remainlen:=flen mod blocklen;

for i:=0 to blocknum-1 do //文件分块的字节块发送
begin
blockread(ftrans,blockbuf[0],blocklen);
idtcpclient1.WriteBuffer(blockbuf,blocklen,false);
end;
if (remainlen>0) then //文件剩余的字节数发送
begin
blockread(ftrans,blockbuf[0],remainlen);
idtcpclient1.WriteBuffer(blockbuf,remainlen,false);
end;
closefile(ftrans);
这个循环要改掉,


[red]WriteBuffer返回的是你实际发送的数据块大小,不一定就是你写到BUFFER里的数据大小[/red]
 
能修改一下吗?
 
const
MAX_LEN=2048;

var
iSen:integer; //iSen发送出去的长度
iSize:integer; //文件长度 最好是全局变量
buf:array[1..MAXLEN]of char;
senlen:integer; //每次应该发送的长度
ret:integer; //实际发送的文件长度
filen:TFileStream; //最好是全局变量

iSen:=0;
while iSen<iSize do
begin
FillChar(buf,MAX_LEN,0);
if iSize-iSen>MAX_LEN then senlen:=MAX_LEN
else senLen:=iSize-iSen;
filen.Position:=iSen;
filen.Read(buf,senLen);
ret:=ClientSocket1.Socket.SendBuf(buf,senLen);
inc(iSen,ret);
end;
我上面的发送部分写清楚了了,???[8D]
 
请把上面的代码修改一下,因为刚接触INDY控件,所以不是很懂,谢谢,改好后分数马上给。
 
兄弟呀,现在用的是INDY控件。
 
我把原理告诉你了,代码自己改,把哪个循环改一下就可以了,最好用
文件流来控制,ASSIGNFILE容易出错
 
加几个变量控制,没改多少呀?
 
可兄弟呀,我不熟悉INDY控件的使用呀!请指教指教。
 
举手之劳,就改一下吧。
 
const
MAX_LEN=2048;

var
iSen:integer; //iSen发送出去的长度
iSize:integer; //文件长度 最好是全局变量
buf:array[1..MAXLEN]of char;
senlen:integer; //每次应该发送的长度
ret:integer; //实际发送的文件长度
filen:TFileStream; //最好是全局变量
//开始的时候要FILEN。CREATE()

iSen:=0;
while iSen<iSize do
begin
FillChar(buf,MAX_LEN,0);
if iSize-iSen>MAX_LEN then senlen:=MAX_LEN
else senLen:=iSize-iSen;
filen.Position:=iSen;
filen.Read(buf,senLen);
ret:= idtcpclient1.WriteBuffer(buf,remainlen,false);
inc(iSen,ret);
end;
 
const
MAX_LEN=2048;

var
iSen:integer; //iSen发送出去的长度
iSize:integer; //文件长度 最好是全局变量
buf:array[1..MAXLEN]of char;
senlen:integer; //每次应该发送的长度
ret:integer; //实际发送的文件长度
filen:TFileStream; //最好是全局变量
//开始的时候要filen:=TFileStream.create();
iSen:=0;
while iSen<iSize do
begin
FillChar(buf,MAX_LEN,0);
if iSize-iSen>MAX_LEN then senlen:=MAX_LEN
else senLen:=iSize-iSen;
filen.Position:=iSen;
filen.Read(buf,senLen);
ret:=idtcpclient1.WriteBuffer(blockbuf,remainlen,false);
inc(iSen,ret);
end;
filen.free;
 
ret:=idtcpclient1.WriteBuffer(blockbuf,remainlen,false);
就改了这个地方而已,[:(]
 
INDY里的控件和CLIENTSOCKET SERVERSOCKET有什么区别?
 
顶部