我有一个客户端应用程序应该将通知消息发送到可选的服务器应用程序。客户端不应受服务器应用程序是否存在的影响。它应该尝试连接到服务器应用程序并发送通知消息,如果出现错误,它应该默默地忽略所有错误并继续工作。
我正在使用Indy进行TCP通信,但是所有尝试避免显示错误消息(即当连接到客户端时服务器应用程序关闭时)都失败了。
有没有办法真正做到这一点?
当前代码如下所示:
if (not Client.Connected) then
begin
Client.Host := ServerName;
Client.Port := ServerPort;
Client.ConnectTimeout := ConnectTimeout;
try
Client.Connect;
except
Exit;
end;
end
try
Client.IOHandler.WriteLn ('NOTIFYCHANGE "' + Param + '"');
Client.IOHandler.WriteBufferFlush;
except
try
Client.Disconnect;
except
{ ignore errors while disconnecting }
end;
try
Client.Connect;
except
{ ignore errors while connecting }
end;
end;
答案 0 :(得分:3)
您是否真的收到来自 计划的错误消息?通常在调试时调试器检测到异常并中断程序,并且有些人将调试器的消息与来自他们自己的程序的消息混淆。你确定不是这里的情况吗? I've written about this situation before.以下是避免它的方法摘要:
如果消息确实来自您的程序而不是调试器,那么请返回使用调试器来确定消息的来源。当消息出现时,暂停程序并查看调用堆栈窗口以查找显示消息的代码区域,因为它显然不在您显示的代码中。您展示的代码彻底压制(不处理)所有异常,甚至是与Indy无关的异常,例如EAccessViolation
和EOutOfMemory
。
答案 1 :(得分:2)
对于简单的TCP通信任务,我使用了Synapse包,它不像Indy那样臃肿,使用起来感觉“更干净”。
从我最近的代码:
procedure SendMessage(m: string);
var
sock : TTCPBlockSocket;
response : string;
begin
Sock := TTCPBlockSocket.Create;
try
Sock.SetTimeout(200);
Sock.Connect(PrinterServerAddr, IntToStr(PrinterServerPort));
Sock.SendString(m);
response := Sock.RecvString(1000);
finally
Sock.Free;
end;
end;
..
try
SendMessage(NewMessage);
except
//..handle exception..
end;
如果你想避免阻止你当前的线程,请将其包裹在TThread中。
答案 2 :(得分:0)
如果可能,请考虑使用UDP。它是“无连接”的,因此发送方只会发送消息,接收应用程序将收到它,如果它正在侦听端口。但是,除非服务器发送某种确认,否则发件人不会获得有关交付的任何确认。
答案 3 :(得分:0)
Harriv响应没问题,您正在描述UDP连接的行为。我在类似的情况下使用。
答案 4 :(得分:0)
你没有说你是否使用Indy 9或10.我自己使用9,所以下面假设这个。
为什么不呢?:
procedure Send(Target: String; Port: Integer; S: String);
var
C: TIdTcpClient;
begin
C := TIdTcpClient.Create(nil);
try
try
C.Host := Target;
C.Port := Port;
C.Connect;
try
C.Write(S);
finally
C.Disconnect;
end;
except
// Ignore Indy exceptions
on EIdException do;
end;
finally
C.Free;
end;
end;
将其转换为使用预先存在的TIdTcpClient的过程很容易。