各位大虾,有谁知道如何处理TServerClientWinSocket类的OnErrorEvent事件,急急急,在线等待,分不够可以加 各位大虾,有谁知道如何处理TServerClientWinSocket类的OnErrorEvent事件,急急急,在线等待,分不够可以加 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我写了一个多线程socket服务器接收图片的程序,可是当有大量图片上传,且网络突然中断的情况就是报系统错误并且主程序关闭,我要解决的问题就是如何正确处理这些系统错误:我的线程代码如下:typeTClientThread = Class(TServerClientThread) private public filename: string; filelen: Longint; DestStream: TMemoryStream; intError :integer; procedure ClientExecute; override; procedure UnCompressBitmap(const CompressedStream: TMemoryStream); procedure show; procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); procedure errorCount; end; ReceiptImage =record thd :TClientThread; blStatus :boolean; end;const C_Client_CanBegin = '111111'; //开始发送请求 C_Client_END = '222222'; //发送完毕 C_Client_FileLenth = '333333'; //文件的长度 C_Server_Begin = '444444'; //回复,可以发送了 C_Server_NextData = '555555'; //下一个文件数据包 C_Server_NeedData = '666666'; //服务器叫客户端送文件上来implementation{$R *.dfm}procedure TClientThread.ClientExecute;var stmp: string; tmp : string; ilength: integer; Buffer: pointer; size: integer; SocketStream : TWinSocketStream; ReceiveBuffer : Array[0..1025] Of Char; BytesRead : Integer; iniFile : TIniFile;begin try FreeOnTerminate :=true; ClientSocket.SendText(C_Server_NeedData); ClientSocket.OnErrorEvent :=doException; while not Terminated and ClientSocket.Connected do Begin try SocketStream := TWinSocketStream.Create(ClientSocket, 5000); try FillChar(ReceiveBuffer, sizeof(ReceiveBuffer), 0); if SocketStream.WaitForData(5000) then begin if Assigned(SocketStream) then begin intError :=0; try BytesRead := SocketStream.Read(ReceiveBuffer,SizeOf(ReceiveBuffer)); except ClientSocket.Close; end; if BytesRead = 0 then begin ClientSocket.Close; end else begin tmp:=ReceiveBuffer; stmp := copy(tmp ,1,6); if stmp = C_Client_CanBegin then //如果收到请求回复以下 begin filename := copy(tmp,7,BytesRead-6); ClientSocket.SendText (C_Server_Begin); end else if stmp = C_Client_FileLenth then //收到文件的长度 begin DestStream := TMemoryStream.Create; filelen := strtoint(copy(tmp,7,BytesRead-6)); ClientSocket.SendText(C_Server_NextData); //开始接收数据 end else if stmp = C_Client_End then //如果数据发送完毕 begin DestStream.Position := 0; UnCompressBitmap(DestStream); DestStream.Free; ClientSocket.Close; Synchronize(show); end else begin DestStream.WriteBuffer(ReceiveBuffer,BytesRead);// ClientSocket.SendText(C_Server_NextData); end; end; end; end else begin //如果连续5次没有收到数据,则认为永远收不到数据。关闭连接 if intError>5 then begin ClientSocket.Close; end else begin inc(intError); end; end; finally freeAndNil(SocketStream); end; except //FreeMem(Buffer,iLength); if Assigned(SocketStream) then SocketStream.Free; if ClientSocket.Connected then ClientSocket.Close; end; end; except if ClientSocket.Connected then ClientSocket.Close; ClientSocket.Free; end;end;procedure TClientThread.UnCompressBitmap(const CompressedStream: TMemoryStream);const ImagePath = 'SoftWare\NetBar\WebApp\';var SourceStream: TDecompressionStream; DestStream: TMemoryStream; Buffer: PChar; Count: LongInt; Path: string; iniFile :TIniFile;Begin try getmem(buffer,filelen); DestStream := TMemoryStream.Create; SourceStream := TDecompressionStream.Create(CompressedStream); Try SourceStream.ReadBuffer(Buffer^, filelen); DestStream.WriteBuffer(Buffer^, filelen); DestStream.Position := 0;//复位流指针 Path := ExtractFilePath(application.ExeName); if not directoryexists(Path) then createdirectory(pchar(Path),0); DestStream.SaveToFile (Path +'\pic\'+filename+'.jpg'); finally FreeMem(Buffer); freeAndNil(DestStream); freeAndNil(SourceStream); end; except if Assigned(Buffer) then FreeMem(Buffer); if Assigned(DestStream) then DestStream.Free; end;end;procedure TClientThread.errorCount;begin form1.Memo2.Lines.Append(fileName);end;procedure TClientThread.doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);begin //这段代码有问题 Socket.Close; Socket.Free; end; 我整理重发一下以上我的原代码:我写了一个多线程socket服务器接收图片的程序,可是当有大量图片上传,且网络突然中断的情况就是报系统错误并且主程序关闭,我要解决的问题就是如何正确处理这些系统错误,我认为主要要解决的问题就是正确处理过程procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);:我的线程代码如下:typeTClientThread = Class(TServerClientThread) private public filename: string; filelen: Longint; DestStream: TMemoryStream; intError :integer; procedure ClientExecute; override; procedure UnCompressBitmap(const CompressedStream: TMemoryStream); procedure show; procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); procedure errorCount; end; ReceiptImage =record thd :TClientThread; blStatus :boolean; end;const C_Client_CanBegin = '111111'; //开始发送请求 C_Client_END = '222222'; //发送完毕 C_Client_FileLenth = '333333'; //文件的长度 C_Server_Begin = '444444'; //回复,可以发送了 C_Server_NextData = '555555'; //下一个文件数据包 C_Server_NeedData = '666666'; //服务器叫客户端送文件上来implementation{$R *.dfm}procedure TClientThread.ClientExecute;var stmp: string; tmp : string; ilength: integer; Buffer: pointer; size: integer; SocketStream : TWinSocketStream; ReceiveBuffer : Array[0..1025] Of Char; BytesRead : Integer; iniFile : TIniFile;begin try FreeOnTerminate :=true; ClientSocket.SendText(C_Server_NeedData); ClientSocket.OnErrorEvent :=doException; while not Terminated and ClientSocket.Connected do Begin try SocketStream := TWinSocketStream.Create(ClientSocket, 5000); try FillChar(ReceiveBuffer, sizeof(ReceiveBuffer), 0); if SocketStream.WaitForData(5000) then begin if Assigned(SocketStream) then begin intError :=0; try BytesRead := SocketStream.Read(ReceiveBuffer,SizeOf(ReceiveBuffer)); except ClientSocket.Close; end; if BytesRead = 0 then begin ClientSocket.Close; end else begin tmp:=ReceiveBuffer; stmp := copy(tmp ,1,6); if stmp = C_Client_CanBegin then //如果收到请求回复以下 begin filename := copy(tmp,7,BytesRead-6); ClientSocket.SendText (C_Server_Begin); end else if stmp = C_Client_FileLenth then //收到文件的长度 begin DestStream := TMemoryStream.Create; filelen := strtoint(copy(tmp,7,BytesRead-6)); ClientSocket.SendText(C_Server_NextData); //开始接收数据 end else if stmp = C_Client_End then //如果数据发送完毕 begin DestStream.Position := 0; UnCompressBitmap(DestStream); DestStream.Free; ClientSocket.Close; end else begin DestStream.WriteBuffer(ReceiveBuffer,BytesRead);// ClientSocket.SendText(C_Server_NextData); end; end; end; end else begin //如果连续5次没有收到数据,则认为永远收不到数据。关闭连接 if intError>5 then begin ClientSocket.Close; end else begin inc(intError); end; end; finally freeAndNil(SocketStream); end; except //FreeMem(Buffer,iLength); if Assigned(SocketStream) then SocketStream.Free; if ClientSocket.Connected then ClientSocket.Close; end; end; except if ClientSocket.Connected then ClientSocket.Close; ClientSocket.Free; end;end;procedure TClientThread.UnCompressBitmap(const CompressedStream: TMemoryStream);const ImagePath = 'SoftWare\NetBar\WebApp\';var SourceStream: TDecompressionStream; DestStream: TMemoryStream; Buffer: PChar; Count: LongInt; Path: string; iniFile :TIniFile;Begin try getmem(buffer,filelen); DestStream := TMemoryStream.Create; SourceStream := TDecompressionStream.Create(CompressedStream); Try SourceStream.ReadBuffer(Buffer^, filelen); DestStream.WriteBuffer(Buffer^, filelen); DestStream.Position := 0;//复位流指针 Path := ExtractFilePath(application.ExeName); if not directoryexists(Path) then createdirectory(pchar(Path),0); DestStream.SaveToFile (Path +'\pic\'+filename+'.jpg'); finally FreeMem(Buffer); freeAndNil(DestStream); freeAndNil(SourceStream); end; except if Assigned(Buffer) then FreeMem(Buffer); if Assigned(DestStream) then DestStream.Free; end;end;procedure TClientThread.errorCount;begin form1.Memo2.Lines.Append(fileName);end;procedure TClientThread.doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);begin //这段代码有问题 Socket.Close; Socket.Free; end; 我看法同你不同。建议楼主先把所有的doException处理的代码删掉。。那些东西主要是为了非阻塞SOCKET设计的。首先看你工作线程里面基本上该抓的异常都已经抓了,这儿应该不会造成系统死掉。剩下一种可能就是你工作线程同主线程造成的冲突。。procedure TClientThread.errorCount;begin form1.Memo2.Lines.Append(fileName);end;这是典型的线程不安全的。。另外,对文件操作也可能资源冲突。。 我这个程序现在主要是报:Access violation at address 77F856A3 in module 'ntdll.dll'.Read of address FF14E4B0 delphi专区这是怎么了。没人讨论,郁闷 halfdream(哈欠) 非常认真的回答了你的问题,不过他只是说 "这是典型的线程不安全的。。"怎么不和他说线程同步呢? procedure TClientThread.doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);begin case errorcode of //错误代码比如 10004: begin showmeeesage('操作被中断'); ErrorCode:=0 end; end; 图片转换问题 急~程序退出时出现Error! Delphi技术论坛QQ群组 DBLookupCombobox问题 那有EHlib7.0(EHDBgrid)的下载? 如何将做好的子窗体用编译成dll调用,急~~~~~~~ 一个菜鸟问关于公共对话框组件的问题 搞了这么多年Delphi, 居然被这个小问题搞死了!大家帮我看一看是不是Delphi的Bug呢 打开子窗体在关闭主窗体后报错 一个关于AVI文件的问题! 使用Delphi调用Dll的问题 求结构数组保存到硬盘的方法
我的线程代码如下:
type
TClientThread = Class(TServerClientThread)
private
public
filename: string;
filelen: Longint;
DestStream: TMemoryStream;
intError :integer;
procedure ClientExecute; override;
procedure UnCompressBitmap(const CompressedStream: TMemoryStream);
procedure show;
procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure errorCount;
end;
ReceiptImage =record
thd :TClientThread;
blStatus :boolean;
end;const C_Client_CanBegin = '111111'; //开始发送请求
C_Client_END = '222222'; //发送完毕
C_Client_FileLenth = '333333'; //文件的长度 C_Server_Begin = '444444'; //回复,可以发送了
C_Server_NextData = '555555'; //下一个文件数据包
C_Server_NeedData = '666666'; //服务器叫客户端送文件上来
implementation{$R *.dfm}procedure TClientThread.ClientExecute;
var
stmp: string;
tmp : string;
ilength: integer;
Buffer: pointer;
size: integer; SocketStream : TWinSocketStream;
ReceiveBuffer : Array[0..1025] Of Char;
BytesRead : Integer;
iniFile : TIniFile;
begin try
FreeOnTerminate :=true;
ClientSocket.SendText(C_Server_NeedData);
ClientSocket.OnErrorEvent :=doException;
while not Terminated and ClientSocket.Connected do
Begin
try
SocketStream := TWinSocketStream.Create(ClientSocket, 5000);
try
FillChar(ReceiveBuffer, sizeof(ReceiveBuffer), 0);
if SocketStream.WaitForData(5000) then
begin
if Assigned(SocketStream) then
begin
intError :=0;
try
BytesRead := SocketStream.Read(ReceiveBuffer,SizeOf(ReceiveBuffer));
except
ClientSocket.Close;
end;
if BytesRead = 0 then
begin
ClientSocket.Close;
end
else
begin
tmp:=ReceiveBuffer;
stmp := copy(tmp ,1,6);
if stmp = C_Client_CanBegin then //如果收到请求回复以下
begin
filename := copy(tmp,7,BytesRead-6);
ClientSocket.SendText (C_Server_Begin);
end
else if stmp = C_Client_FileLenth then //收到文件的长度
begin
DestStream := TMemoryStream.Create;
filelen := strtoint(copy(tmp,7,BytesRead-6));
ClientSocket.SendText(C_Server_NextData); //开始接收数据
end
else if stmp = C_Client_End then //如果数据发送完毕
begin
DestStream.Position := 0;
UnCompressBitmap(DestStream);
DestStream.Free;
ClientSocket.Close;
Synchronize(show);
end
else
begin
DestStream.WriteBuffer(ReceiveBuffer,BytesRead);//
ClientSocket.SendText(C_Server_NextData); end;
end;
end;
end
else
begin
//如果连续5次没有收到数据,则认为永远收不到数据。关闭连接
if intError>5 then
begin
ClientSocket.Close;
end
else
begin
inc(intError);
end;
end;
finally
freeAndNil(SocketStream);
end;
except
//FreeMem(Buffer,iLength);
if Assigned(SocketStream) then SocketStream.Free;
if ClientSocket.Connected then ClientSocket.Close;
end;
end;
except
if ClientSocket.Connected then ClientSocket.Close;
ClientSocket.Free;
end;
end;procedure TClientThread.UnCompressBitmap(const CompressedStream: TMemoryStream);
const
ImagePath = 'SoftWare\NetBar\WebApp\';
var
SourceStream: TDecompressionStream;
DestStream: TMemoryStream;
Buffer: PChar;
Count: LongInt;
Path: string;
iniFile :TIniFile;
Begin
try
getmem(buffer,filelen);
DestStream := TMemoryStream.Create;
SourceStream := TDecompressionStream.Create(CompressedStream);
Try
SourceStream.ReadBuffer(Buffer^, filelen);
DestStream.WriteBuffer(Buffer^, filelen);
DestStream.Position := 0;//复位流指针
Path := ExtractFilePath(application.ExeName);
if not directoryexists(Path) then createdirectory(pchar(Path),0);
DestStream.SaveToFile (Path +'\pic\'+filename+'.jpg');
finally
FreeMem(Buffer);
freeAndNil(DestStream);
freeAndNil(SourceStream);
end;
except
if Assigned(Buffer) then FreeMem(Buffer);
if Assigned(DestStream) then DestStream.Free;
end;
end;
procedure TClientThread.errorCount;
begin
form1.Memo2.Lines.Append(fileName);
end;procedure TClientThread.doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
//这段代码有问题
Socket.Close;
Socket.Free;
end;
我写了一个多线程socket服务器接收图片的程序,可是当有大量图片上传,且网络突然中断的情况就是报系统错误并且主程序关闭,我要解决的问题就是如何正确处理这些系统错误,我认为主要要解决的问题就是正确处理过程procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);:
我的线程代码如下:
type
TClientThread = Class(TServerClientThread)
private
public
filename: string;
filelen: Longint;
DestStream: TMemoryStream;
intError :integer;
procedure ClientExecute; override;
procedure UnCompressBitmap(const CompressedStream: TMemoryStream);
procedure show;
procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure errorCount;
end;
ReceiptImage =record
thd :TClientThread;
blStatus :boolean;
end;const C_Client_CanBegin = '111111'; //开始发送请求
C_Client_END = '222222'; //发送完毕
C_Client_FileLenth = '333333'; //文件的长度 C_Server_Begin = '444444'; //回复,可以发送了
C_Server_NextData = '555555'; //下一个文件数据包
C_Server_NeedData = '666666'; //服务器叫客户端送文件上来
implementation{$R *.dfm}procedure TClientThread.ClientExecute;
var
stmp: string;
tmp : string;
ilength: integer;
Buffer: pointer;
size: integer; SocketStream : TWinSocketStream;
ReceiveBuffer : Array[0..1025] Of Char;
BytesRead : Integer;
iniFile : TIniFile;
begin try
FreeOnTerminate :=true;
ClientSocket.SendText(C_Server_NeedData);
ClientSocket.OnErrorEvent :=doException;
while not Terminated and ClientSocket.Connected do
Begin
try
SocketStream := TWinSocketStream.Create(ClientSocket, 5000);
try
FillChar(ReceiveBuffer, sizeof(ReceiveBuffer), 0);
if SocketStream.WaitForData(5000) then
begin
if Assigned(SocketStream) then
begin
intError :=0;
try
BytesRead := SocketStream.Read(ReceiveBuffer,SizeOf(ReceiveBuffer));
except
ClientSocket.Close;
end;
if BytesRead = 0 then
begin
ClientSocket.Close;
end
else
begin
tmp:=ReceiveBuffer;
stmp := copy(tmp ,1,6);
if stmp = C_Client_CanBegin then //如果收到请求回复以下
begin
filename := copy(tmp,7,BytesRead-6);
ClientSocket.SendText (C_Server_Begin);
end
else if stmp = C_Client_FileLenth then //收到文件的长度
begin
DestStream := TMemoryStream.Create;
filelen := strtoint(copy(tmp,7,BytesRead-6));
ClientSocket.SendText(C_Server_NextData); //开始接收数据
end
else if stmp = C_Client_End then //如果数据发送完毕
begin
DestStream.Position := 0;
UnCompressBitmap(DestStream);
DestStream.Free;
ClientSocket.Close;
end
else
begin
DestStream.WriteBuffer(ReceiveBuffer,BytesRead);//
ClientSocket.SendText(C_Server_NextData); end;
end;
end;
end
else
begin
//如果连续5次没有收到数据,则认为永远收不到数据。关闭连接
if intError>5 then
begin
ClientSocket.Close;
end
else
begin
inc(intError);
end;
end;
finally
freeAndNil(SocketStream);
end;
except
//FreeMem(Buffer,iLength);
if Assigned(SocketStream) then SocketStream.Free;
if ClientSocket.Connected then ClientSocket.Close;
end;
end;
except
if ClientSocket.Connected then ClientSocket.Close;
ClientSocket.Free;
end;
end;procedure TClientThread.UnCompressBitmap(const CompressedStream: TMemoryStream);
const
ImagePath = 'SoftWare\NetBar\WebApp\';
var
SourceStream: TDecompressionStream;
DestStream: TMemoryStream;
Buffer: PChar;
Count: LongInt;
Path: string;
iniFile :TIniFile;
Begin
try
getmem(buffer,filelen);
DestStream := TMemoryStream.Create;
SourceStream := TDecompressionStream.Create(CompressedStream);
Try
SourceStream.ReadBuffer(Buffer^, filelen);
DestStream.WriteBuffer(Buffer^, filelen);
DestStream.Position := 0;//复位流指针
Path := ExtractFilePath(application.ExeName);
if not directoryexists(Path) then createdirectory(pchar(Path),0);
DestStream.SaveToFile (Path +'\pic\'+filename+'.jpg');
finally
FreeMem(Buffer);
freeAndNil(DestStream);
freeAndNil(SourceStream);
end;
except
if Assigned(Buffer) then FreeMem(Buffer);
if Assigned(DestStream) then DestStream.Free;
end;
end;
procedure TClientThread.errorCount;
begin
form1.Memo2.Lines.Append(fileName);
end;procedure TClientThread.doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
//这段代码有问题
Socket.Close;
Socket.Free;
end;
建议楼主先把所有的doException处理的代码删掉。。那些东西主要是为了非阻塞SOCKET设计的。首先看你工作线程里面基本上该抓的异常都已经抓了,这儿应该不会造成系统死掉。
剩下一种可能就是你工作线程同主线程造成的冲突。。procedure TClientThread.errorCount;
begin
form1.Memo2.Lines.Append(fileName);
end;
这是典型的线程不安全的。。
另外,对文件操作也可能资源冲突。。
没人讨论,郁闷
不过他只是说 "这是典型的线程不安全的。。"
怎么不和他说线程同步呢?
begin
case errorcode of
//错误代码比如
10004:
begin
showmeeesage('操作被中断');
ErrorCode:=0
end;
end;