Delphi 2007,Indy 10 - 单向传输数据块的最简单的 TCP/IP 设置是什么
Delphi 2007, Indy 10 - What is the simplest TCP/IP setup for transferring a block of data in one direction
我有一个应用程序("server")每秒更新内存中的一个数据块 - 大约 100k 字节。
"client" 应用程序 运行ning 在同一网络上的其他工作站上还有 1 到 4 个其他实例,这些实例每秒需要读取相同的 100k 图像。
到目前为止,这是通过将图像写入服务器上的文件并让客户端通过网络从该文件中读取来实现的。这多年来一直没有问题,但最近(恰逢转向 windows 基于 8 的硬件)它出现了一个问题,即除一个节点外,所有节点都无法访问该文件。在此节点上退出客户端应用程序 运行ning 会释放文件,然后所有人都可以再次访问它。
对于此锁定的原因,我仍然感到困惑,但我想知道这是否可能是所讨论的机制 here,其中文件由于网络故障而未关闭。我认为让客户通过 TCP/IP 请求数据可以避免这种情况。
除了客户端无法连接或读取数据外,不需要任何握手 - 服务器只需要处理它的业务并通过获取数据并发送它来响应请求。然而,我对实现这一目标的最佳架构非常模糊。 TidTCPClient 和 TidTCPServer 会砍掉它吗?我假设客户端会在一个线程中请求数据,但这是否意味着服务器需要 运行 一个线程不断地响应请求?
TIdTCPServer
是多线程组件。它的客户端 运行 在它为您管理的工作线程中。您所要做的就是实现 OnExecute
事件来发送您的数据。
TIdTCPClient
不是多线程组件。它 运行 在您使用它的任何线程中。因此,如果您需要连续读取数据,最好 运行 您自己的工作线程来处理读取。 Indy 有一个包装线程的 TIdThreadComponent
组件,或者您可以手动编写自己的 TThread
代码。
100K 不是很多数据,所以我建议完全忘记该文件,而是在内存中分配一个缓冲区。您的 TIdTCPServer.OnExecute
事件处理程序可以在需要时从该缓冲区中读取。而且我什至不会费心让客户端请求数据,只需让服务器不断将最新数据推送给活跃的客户端即可。
尝试这样的事情:
服务器:
var
Buffer: TIdBytes;
Lock: TMREWSync;
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
Lock.BeginRead;
try
AContext.Connection.IOHandler.Write(Buffer);
finally
Lock.EndRead;
end;
Sleep(1000);
end;
procedure TForm1.UpdateBuffer;
begin
Lock.BeginWrite;
try
// update the Buffer content as needed...
finally
Lock.EndWrite;
end;
end;
initialization
Lock := TMREWSync.Create;
SetLength(Buffer, 1024 * 100);
finalization
SetLength(Buffer, 0);
Lock.Free;
客户:
procedure TForm1.IdThreadComponent1Run(Sender: TIdThreadComponent);
var
Buffer: TIdBytes;
begin
IdTCPClient1.IOHandler.ReadBytes(Buffer, 1024 * 100);
// use Buffer as needed...
end;
procedure TForm1.Connect;
begin
IdTCPClient1.Connect;
try
IdThreadComponent1.Start;
except
IdTCPClient1.Disconnect;
raise;
end;
end;
procedure TForm1.Disconnect;
begin
IdTCPClient1.Disconnect;
IdThreadComponent1.Stop;
end;
我有一个应用程序("server")每秒更新内存中的一个数据块 - 大约 100k 字节。
"client" 应用程序 运行ning 在同一网络上的其他工作站上还有 1 到 4 个其他实例,这些实例每秒需要读取相同的 100k 图像。
到目前为止,这是通过将图像写入服务器上的文件并让客户端通过网络从该文件中读取来实现的。这多年来一直没有问题,但最近(恰逢转向 windows 基于 8 的硬件)它出现了一个问题,即除一个节点外,所有节点都无法访问该文件。在此节点上退出客户端应用程序 运行ning 会释放文件,然后所有人都可以再次访问它。
对于此锁定的原因,我仍然感到困惑,但我想知道这是否可能是所讨论的机制 here,其中文件由于网络故障而未关闭。我认为让客户通过 TCP/IP 请求数据可以避免这种情况。
除了客户端无法连接或读取数据外,不需要任何握手 - 服务器只需要处理它的业务并通过获取数据并发送它来响应请求。然而,我对实现这一目标的最佳架构非常模糊。 TidTCPClient 和 TidTCPServer 会砍掉它吗?我假设客户端会在一个线程中请求数据,但这是否意味着服务器需要 运行 一个线程不断地响应请求?
TIdTCPServer
是多线程组件。它的客户端 运行 在它为您管理的工作线程中。您所要做的就是实现 OnExecute
事件来发送您的数据。
TIdTCPClient
不是多线程组件。它 运行 在您使用它的任何线程中。因此,如果您需要连续读取数据,最好 运行 您自己的工作线程来处理读取。 Indy 有一个包装线程的 TIdThreadComponent
组件,或者您可以手动编写自己的 TThread
代码。
100K 不是很多数据,所以我建议完全忘记该文件,而是在内存中分配一个缓冲区。您的 TIdTCPServer.OnExecute
事件处理程序可以在需要时从该缓冲区中读取。而且我什至不会费心让客户端请求数据,只需让服务器不断将最新数据推送给活跃的客户端即可。
尝试这样的事情:
服务器:
var
Buffer: TIdBytes;
Lock: TMREWSync;
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
Lock.BeginRead;
try
AContext.Connection.IOHandler.Write(Buffer);
finally
Lock.EndRead;
end;
Sleep(1000);
end;
procedure TForm1.UpdateBuffer;
begin
Lock.BeginWrite;
try
// update the Buffer content as needed...
finally
Lock.EndWrite;
end;
end;
initialization
Lock := TMREWSync.Create;
SetLength(Buffer, 1024 * 100);
finalization
SetLength(Buffer, 0);
Lock.Free;
客户:
procedure TForm1.IdThreadComponent1Run(Sender: TIdThreadComponent);
var
Buffer: TIdBytes;
begin
IdTCPClient1.IOHandler.ReadBytes(Buffer, 1024 * 100);
// use Buffer as needed...
end;
procedure TForm1.Connect;
begin
IdTCPClient1.Connect;
try
IdThreadComponent1.Start;
except
IdTCPClient1.Disconnect;
raise;
end;
end;
procedure TForm1.Disconnect;
begin
IdTCPClient1.Disconnect;
IdThreadComponent1.Stop;
end;