下面的我测试socket分段传文件的代码,文件能传过去,打开时说文件已损坏,但是字节数又没错,请教大家,,急!!!
发送代码-----
implementation
var filestream:Tfilestream;
fis,filesize:integer;
const subsize =2000;
procedure TForm1.Button2Click(Sender: TObject);
begin filestream:=Tfilestream.Create(edit1.Text,fmopenread);
filestream.Position:=0;
filesize:=filestream.Size;
fis:=filesize;
//由于测试没有设计协议,这里只能传五位数字节的文件
clients.Socket.SendText('begin'+inttostr(fis)+'e:\delphi.rar');
memo1.Lines.Clear;
end;
procedure TForm1.ClientsRead(Sender: TObject; Socket: TCustomWinSocket);
var f:pointer;
str:string;
begin
str:=socket.ReceiveText;
memo1.Lines.Add(str);
if (trim(str)='ok') then
begin
memo1.Lines.Add('----正在发送数据----');
getmem(f,subsize);
while fis>0 do
begin
sleep(20);
if fis>2000 then
begin
filestream.Read(f^,subsize);
socket.SendBuf(f^,subsize);
fis:=fis-subsize;
memo1.Lines.Add('剩余字节数'+inttostr(fis));
end
else
begin
filestream.Read(f^,fis);
socket.SendBuf(f^,fis);
fis:=0;
memo1.Lines.Add('剩余字节数'+inttostr(fis));
sleep(1000);
socket.SendText('over');
freemem(f);
end;
end;
memo1.Lines.Add('----发送数据成功----'); end;
end;接收代码--------
type
fileinfo=record
filename:string;
filesize:integer;
subP:pointer;
end;
implementation
var isfile:boolean;
filestream:Tfilestream;
fl:fileinfo;
const subsize=2000;procedure TForm1.ServersClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var substr:string;
begin
sleep(10);
substr:=trim(socket.ReceiveText);
memo1.Lines.Add(substr);
if copy(substr,1,5)='begin' then
begin
fl.filename:=trim(copy(substr,11,20));
memo1.Lines.Add(fl.filename);
fl.filesize:=strtoint(trim(copy(substr,6,5)));
memo1.Lines.Add(inttostr(fl.filesize));
getmem(fl.subP,2000);
isfile:=true;
filestream:=Tfilestream.Create(fl.filename,fmCreate or fmOpenWrite);
filestream.Position:=0;
socket.SendText('ok');
end; if trim(substr)='over' then
begin
isfile:=false;
filestream.Free;
freemem(fl.subP);
exit;
end;
if isfile then
begin
if (fl.filesize>0) then
if (fl.filesize>2000) then
begin
socket.ReceiveBuf(fl.subP^,2000);
filestream.Write(fl.subP^,2000);
fl.filesize:=fl.filesize-2000;
end
else
begin
socket.ReceiveBuf(fl.subP^,fl.filesize);
filestream.Write(fl.subP^,fl.filesize);
fl.filesize:=0;
end;
end;
end;
发送代码-----
implementation
var filestream:Tfilestream;
fis,filesize:integer;
const subsize =2000;
procedure TForm1.Button2Click(Sender: TObject);
begin filestream:=Tfilestream.Create(edit1.Text,fmopenread);
filestream.Position:=0;
filesize:=filestream.Size;
fis:=filesize;
//由于测试没有设计协议,这里只能传五位数字节的文件
clients.Socket.SendText('begin'+inttostr(fis)+'e:\delphi.rar');
memo1.Lines.Clear;
end;
procedure TForm1.ClientsRead(Sender: TObject; Socket: TCustomWinSocket);
var f:pointer;
str:string;
begin
str:=socket.ReceiveText;
memo1.Lines.Add(str);
if (trim(str)='ok') then
begin
memo1.Lines.Add('----正在发送数据----');
getmem(f,subsize);
while fis>0 do
begin
sleep(20);
if fis>2000 then
begin
filestream.Read(f^,subsize);
socket.SendBuf(f^,subsize);
fis:=fis-subsize;
memo1.Lines.Add('剩余字节数'+inttostr(fis));
end
else
begin
filestream.Read(f^,fis);
socket.SendBuf(f^,fis);
fis:=0;
memo1.Lines.Add('剩余字节数'+inttostr(fis));
sleep(1000);
socket.SendText('over');
freemem(f);
end;
end;
memo1.Lines.Add('----发送数据成功----'); end;
end;接收代码--------
type
fileinfo=record
filename:string;
filesize:integer;
subP:pointer;
end;
implementation
var isfile:boolean;
filestream:Tfilestream;
fl:fileinfo;
const subsize=2000;procedure TForm1.ServersClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var substr:string;
begin
sleep(10);
substr:=trim(socket.ReceiveText);
memo1.Lines.Add(substr);
if copy(substr,1,5)='begin' then
begin
fl.filename:=trim(copy(substr,11,20));
memo1.Lines.Add(fl.filename);
fl.filesize:=strtoint(trim(copy(substr,6,5)));
memo1.Lines.Add(inttostr(fl.filesize));
getmem(fl.subP,2000);
isfile:=true;
filestream:=Tfilestream.Create(fl.filename,fmCreate or fmOpenWrite);
filestream.Position:=0;
socket.SendText('ok');
end; if trim(substr)='over' then
begin
isfile:=false;
filestream.Free;
freemem(fl.subP);
exit;
end;
if isfile then
begin
if (fl.filesize>0) then
if (fl.filesize>2000) then
begin
socket.ReceiveBuf(fl.subP^,2000);
filestream.Write(fl.subP^,2000);
fl.filesize:=fl.filesize-2000;
end
else
begin
socket.ReceiveBuf(fl.subP^,fl.filesize);
filestream.Write(fl.subP^,fl.filesize);
fl.filesize:=0;
end;
end;
end;
解决方案 »
- 在界面上添加fastreport4.0报表出错,谁能帮忙看看,困扰几天了
- TDataSource 里的dataset 找不到 TADOQuery..?
- 请大家帮助提供一个Clientdataset和JSON之间相互转换的方法
- 用adodataset、adoconnection控件实现点击DBRrid的title进行排序的问题
- 关于串口通讯的问题,请大侠帮忙看看
- 在线等!!!我要死掉了,是用QR的childband分组的问题,谁能帮我?
- 请各位帮忙
- 如何得到Frame所在窗体的名称,很简单。
- 一个难度高的算法问题,是数据结构上的题目,高手帮忙!!
- to 管理员:
- 如何取局域网内运程主机的多个ip???
- ClientSocket的Onread事件读取BUF的长度怎么设定?
帧头,帧尾,起始帧,结束帧,以及重发机制
这样实现起来会更好些
能说得详细一点吗,是不是这样,发送端先发一条协议,服务端收到后回复一条协议,发送端再发一包数据,这样循环发送,
可是怎么接收,接收时怎么判断哪些数据包是文件数据那些是协议包?