【发布时间】:2016-02-24 14:53:32
【问题描述】:
我在构建 Indy Server/Clients 实时监控系统时遇到了一个重要问题... 我用的是DELPHI 2010,Indy版本是10.5.5............ 我的目的是许多客户端PC连续(4~10fps)向服务器发送屏幕截图,服务器必须将这些屏幕截图帧发送到一些监控PC。 也就是说……
Many clients -----send streams--------> to Server
Some monitors <---receive streams----- from Server
当然,在一台客户端和一台监视器与服务器的情况下工作得很好...... 但是,如果连接另一个客户端或监视器,则服务器会引发异常“地址 000000000 ..... 的访问冲突”或“无效的指针操作”并断开客户端的连接或监视器的连接。
结果,客户端或监视器将与服务器断开连接......
我使用了 idTCPClient 组件,描述了客户端和使用线程发送和接收流的监控代码。 我确信客户端和监视器端的代码没有问题...... 但我认为服务器端绝对会有问题。
对于服务器端,我使用了两个 TidTCPServer 控件... 一种是从客户端PC接收流,另一种是向监控PC发送流。
服务器代码如下...
{one side----idTCPServerRecv is to receive screenshot streams from clients}
procedure TIndyServerForm.IdTCPServer_RecvExecute(AContext: TIdContext);
var
Hb: TIdIOHandler;
TempStr: TStrings;
begin
Hb := AContext.Connection.IOHandler;
if Not Hb.InputBufferIsEmpty then
Begin
Hb.CheckForDisconnect(True, True);
AContext.Connection.IOHandler.CheckForDisconnect(True, True);
recv_Stream := TMemoryStream.Create;
recv_Stream.Clear;
if (ReceiveStream(AContext, TStream(recv_Stream)) = False) then
begin
ROutMsg :=AContext.Binding.PeerIP+' -> receiving failed: ' + IntToStr(recv_Stream.Size)+'byte';
recv_Stream.Free;
Exit;
end;
if recv_Stream.Size < 1024 then
begin
recv_Stream.Seek(0, soFromBeginning);
ROutMsg :=AContext.Binding.PeerIP+' -> captionString received('+
IntToStr(recv_Stream.Size)+' byte) : "'+StringFromStream(TStream(recv_Stream))+'"';
recv_Stream.Free;
end
else
begin
ROutMsg :=AContext.Binding.PeerIP+' -> screenshot received: ' + KBStr(recv_Stream.Size)+' KB';
if G_Sendable = False then
begin
send_Stream:=TMemoryStream.Create;
send_Stream.Clear;
recv_Stream.Seek(0, soFromBeginning);
send_Stream.Seek(0, soFromBeginning);
send_Stream.CopyFrom(recv_Stream, recv_Stream.Size);
G_Sendable :=True;
end;
recv_Stream.Free;
end;
end;
Application.ProcessMessages;
WaitForSingleObject(Handle, 1);
end;
{another side----idTCPServerSend is to send screenshot streams to monitors}
procedure TIndyServerForm.IdTCPServer_SendExecute(AContext: TIdContext);
begin
if G_Sendable then
begin
send_Stream.Seek(0,soFromBeginning);
if (SendStream(AContext, TStream(send_Stream)) = False) then
begin
SOutMsg :=AContext.Binding.PeerIP+' -> sending failed -> ' + KBStr(send_Stream.Size)+' KB';
send_Stream.Free;
G_Sendable :=False;
Exit;
end;
SOutMsg :=AContext.Binding.PeerIP+' -> sending successful-> ' + KBStr(send_Stream.Size)+' KB';
send_Stream.Free;
G_Sendable :=False;
end;
Application.ProcessMessages;
WaitForSingleObject(Handle, 1);
end;
对于具有实时流交换的多客户端连接,我应该怎么做... 每台客户端 PC 每秒发送 4~10 次截图流... 并且这些流必须发送到相应的监视器 请给我建议....
【问题讨论】:
标签: multithreading delphi indy indy10 server-push