关于socket的传送文件,有点问题,大家帮忙测试,找出原因,共同提高(100分)

  • 主题发起人 主题发起人 ifeng
  • 开始时间 开始时间
I

ifeng

Unregistered / Unconfirmed
GUEST, unregistred user!
大家帮忙测试一下吧,有错误,搞了一天没搞出来
客户和服务均为阻塞方式,这端程序我也是从网上学来的
如果测试修改完毕,经我调试没错误后,马上给分!

客户端
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, ComCtrls, StdCtrls, Buttons, Menus, OnlineIP, ExtCtrls;

type
TForm1 = class(TForm)
CS_Send: TClientSocket;
SBar: TStatusBar;
labfile: TLabel;
OpenDialog1: TOpenDialog;
OnlineIP1: TOnlineIP;
Panel1: TPanel;
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
btnSend: TBitBtn;
btnOpenfile: TBitBtn;
edtHost: TEdit;
edtfile: TEdit;
procedure FormCreate(Sender: TObject);
procedure btnSendClick(Sender: TObject);
procedure OnlineIP1Changed(Sender: TObject);
procedure SBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
const Rect: TRect);
procedure btnOpenfileClick(Sender: TObject);
private
{ Private declarations }
FileSizes_C : array [0..10] of char;
iFileSizes :integer;
SendFile :File of byte;
m,n,i :integer;
Progress : TProgressBar;
ProgressRect : TRect;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
btnSend.Enabled := false;
end;

procedure TForm1.btnSendClick(Sender: TObject);
var
MyClientSockets:TWinSocketStream;
ReadBuffer :array [0..1023] of Byte;
ReceiveText :array [0..99] of char;
SendText :array [0..99] of char;
Text :String;
NumRead :integer;
begin
Progress := TProgressBar.Create(Form1);
Progress.Top := ProgressRect.Top;
Progress.Left := ProgressRect.Left;
Progress.Width := ProgressRect.Right - ProgressRect.Left;
Progress.Height := ProgressRect.Bottom - ProgressRect.Top;
Progress.Parent := SBar;
Progress.Position :=0;
i := SizeOf(ReadBuffer);
MyClientSockets:=TWinSocketStream.Create (CS_Send.Socket,20);
StrPCopy(FileSizes_C,IntToStr(FileSize(SendFile)));
Text := OpenDialog1.FileName +';'+ IntToStr(FileSize(SendFile));
StrPCopy(SendText,Text);
MyClientSockets.Write(SendText,SizeOf(SendText));
MyClientSockets.WaitForData (1000);
MyClientSockets.Read(ReceiveText,SizeOf(ReceiveText));
Text := StrPas(ReceiveText);
if Text = 'Ok' then
begin
Seek(SendFile,soFromBeginning);
while iFileSizes>0 do
begin
BlockRead(SendFile,ReadBuffer,SizeOf(ReadBuffer),NumRead);
MyClientSockets.Write(ReadBuffer,NumRead);
iFileSizes := iFileSizes-NumRead;

if i>=StrToInt(FileSizes_C) then
Progress.Position := 100
else
begin
n := Trunc(100*i/StrToInt(FileSizes_C));
if n=m then
begin
Progress.Stepit;
m := m+1;
end;
end;
i := i+SizeOf(ReadBuffer);

end;
end;
CloseFile(SendFile);
MyClientSockets.WaitForData (1000);
MyClientSockets.Read(ReceiveText,SizeOf(ReceiveText));
Text := StrPas(ReceiveText);
if Text = 'Finished' then
Application.MessageBox('传送完成!','信息',MB_OK+MB_ICONINFORMATION);
Progress.Free;
MyClientSockets.Free;
edtfile.Text := '';
btnSend.Enabled := false;
end;

procedure TForm1.OnlineIP1Changed(Sender: TObject);
begin
if OnlineIP1.Online then
edthost.Text := OnlineIP1.IP;
end;

procedure TForm1.SBarDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
const Rect: TRect);
begin
ProgressRect := Rect;
end;

procedure TForm1.btnOpenfileClick(Sender: TObject);
begin
if not CS_Send.Active then
begin
if Application.MessageBox('确定吗?','询问',MB_OKCancel+MB_iconInformation)=IDOk then
begin
try
CS_Send.Host := trim(edtHost.text);
CS_Send.Active := true;
btnSend.Enabled := true;
//Application.MessageBox('','',MB_OK+MB_iconInformation);
except
//Application.MessageBox('','',MB_OK+MB_ICONWARNING);
Exit;
end;
end
else
Exit;
end;
m := 1;
if OpenDialog1.Execute then
begin
SBar.Panels[0].Text:= '文件:'+ExtractFileName(OpenDialog1.FileName);
edtfile.Text := OpenDialog1.FileName;
AssignFile(SendFile,OpenDialog1.FileName);
Reset(SendFile);
iFileSizes := FileSize(SendFile);
SBar.Panels[1].Text:= '大小:'+IntToStr(iFileSizes)+' 字节';
end;
end;

end.

//服务端

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, ComCtrls, StdCtrls, Buttons, Menus, OnlineIP, ExtCtrls;

type
TForm1 = class(TForm)
SS_Send: TServerSocket;
labfile: TLabel;
OnlineIP1: TOnlineIP;
Panel1: TPanel;
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
edtHost: TEdit;
procedure FormCreate(Sender: TObject);
procedure OnlineIP1Changed(Sender: TObject);
procedure SS_SendGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
private
{ Private declarations }
public
{ Public declarations }
end;

TSendThread = class(TServerClientThread)
private
//FMemoFileInfo :TMemo;
FileSizes :String;
FileName :String;
MySockets:TWinSocketStream;
protected
procedure Execute; override;
public
TWinSkt:TServerClientWinSocket;
procedure GetFileNameAndSize(Text :String);
//procedure ReceiveFileInfo;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TSendThread.GetFileNameAndSize(Text :String);
var iPos :integer;
begin
iPos :=Pos(';',Text);
FileName := Copy(Text,1,iPos-1);
FileSizes := Copy(Text,iPos+1,Length(Text));
end;

{procedure TSendThread.ReceiveFileInfo;
begin
//FMemoFileInfo := TMemo.Create(Application);
//FMemoFileInfo.Parent:=Form1;
//FMemoFileInfo.Lines.Add(FileSizes+FileName);
end;}

procedure TSendThread.Execute;
var
ReceiveFile :File of Byte ;
WriteBuffer :array [0..1023] of Byte;
ReceiveText :array [0..99] of char;
SendText :array [0..99] of char;
Text :String;
InTransmiting :Boolean;
begin
InTransmiting := false;
while (not Terminated) and (TWinSkt.Connected) do
begin
try
MySockets:=TWinSocketStream.Create(TWinSkt,100000);
try
if not InTransmiting then
begin
MySockets.WaitForData (6000);
MySockets.Read(ReceiveText,SizeOf(ReceiveText));
Text := StrPas(ReceiveText);
if Length(Text) > 0 then
begin
GetFileNameAndSize(Text);{得到文件信息}
AssignFile(ReceiveFile,'c:/'+ExtractFileName(FileName));
Rewrite(ReceiveFile);
SendText := 'Ok';
MySockets.Write(SendText,SizeOf(SendText));
InTransmiting := true;
end;
end
else
begin
while StrToInt(FileSizes)>0 do
begin
if StrToInt(FileSizes)<=SizeOf(WriteBuffer) then
begin
MySockets.WaitForData (6000);
MySockets.Read(WriteBuffer,StrToInt(FileSizes));
BlockWrite(ReceiveFile,WriteBuffer,StrToInt(FileSizes));
FileSizes := IntToStr(StrToInt(FileSizes)-StrToInt(FileSizes));
end
else
begin
MySockets.WaitForData (6000);
MySockets.Read(WriteBuffer,SizeOf(WriteBuffer));
BlockWrite(ReceiveFile,WriteBuffer,SizeOf(WriteBuffer));
FileSizes := IntToStr(StrToInt(FileSizes)-SizeOf(WriteBuffer));
end;
end;
CloseFile(ReceiveFile);
SendText := 'Finished';
MySockets.Write(SendText,SizeOf(SendText));
InTransmiting := False;
end;
finally
MySockets.Free;
end;
except
TWinSkt.Close;
end;
end;
end;

////

procedure TForm1.FormCreate(Sender: TObject);
begin
SS_Send.Active := true;
end;


procedure TForm1.OnlineIP1Changed(Sender: TObject);
begin
if OnlineIP1.Online then
edthost.Text := OnlineIP1.IP;
end;

procedure TForm1.SS_SendGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
var
MyThd:TSendThread;
begin
MyThd:=TSendThread.Create(false,ClientSocket) ;
MyThd.TWinSkt :=ClientSocket;
SocketThread:=MyThd;
end;

end.
 
出了问题了?[8D]
 
是这样的,在客户端提示传送完文件后,关闭客户端程序,服务端包错,并且查看文件
并没有传结束。
而先关闭服务端程序,则不会出现上述问题,文件也传结束。
怎么回事??希望能给我一个圆满的解释,谢谢先
 
你在本机调式可能出这个问题,在不同的机器上连接测试,应该是正常的
 
在不同的机器上测试,客户端出现下列错误:
“Read eroor 64 ,指定的网络名不可再用”
怎么回事?
 
连接失败了,
 
怎么会这样,我是在文件快传结束的时候报错。
为什么到这个时候还连接失败呢
 
我把服务端的



except
TWinSkt.Close;
end;
end;
改为:



except
//TWinSkt.Close;
end;
end;
不报错了,但所传的zip文件打不开。(不在同一个机器上)
但在同一个机器上,在先关闭服务端的情况下,所传文件可以打开
怎么回事?请大侠指点
 
原因很简单,本机上TCP是用一个通道通讯,和不是在本机有一些地方不一样,尤其是
服务器和客户机的关闭先后次顺
 
最重要的一点是在本机上调式,发送方发送完所有的数据后,不要马上关闭连接,
先sleep()几秒在关闭,这样接收方的数据就没有问题,在非本机调试的情况吓就
不用这个麻烦。
 
谢谢张大侠的回答,收藏
如果用非阻塞方式,如何在服务端实时监听客户端,采用什么方法比较好?
不好意思,老是问问题。
 
多人接受答案了。
 
后退
顶部