0

我有一个使用 Indy 9 的小型客户端-服务器应用程序项目。我的服务器应用程序正在使用“命令处理程序”来处理客户端的命令。在这种情况下,我的客户端应用程序使用writeLn过程来发送基于文本的命令和数据。例如:

IdTcpClient1.WriteLn('cmd1'+'#'+'hello server');

注意:'cmd1' 是命令,'#' 是命令分隔符,'hello server' 是数据

为了处理这个命令(cmd1),我的服务器应用程序有一个过程如下:

procedure TForm1.IdTcpServer1cmd1Command(Asender:TIdCommand);
var
  s: string;
begin   
  if ( Assigned(ASender.Params) ) then
  begin
    s:= Asender.Param[0];
    ...............
    ...............
  end;
end;

到目前为止一切都很好。问题是我想添加一个功能,以便我的服务器应用程序能够从客户端请求和接收 JPEG_image。如果客户端使用:WriteStream过程发送此图像,例如:

IdTcpClient1.WriteStream(MyImageStream);

考虑到没有特定命令(例如本例中的“cmd1”),服务器如何处理此事件?

4

2 回答 2

1

您只需调用ReadStream()命令处理程序,例如:

IdTcpClient1.WriteLn('JPEG');
IdTcpClient1.WriteStream(MyImageStream, True, True); // AWriteByteCount=True

procedure TForm1.IdTcpServer1JPEGCommand(ASender: TIdCommand);
var
  Strm: TMemoryStream;
begin   
  ...
  Strm := TMemoryStream.Create;
  try
    ASender.Thread.Connection.ReadStream(Strm); // expects AWriteByteCount=True by default
    ...
  finally
    Strm.Free;
  end;
  ...
end;

或者:

IdTcpClient1.WriteLn('JPEG#' + IntToStr(MyImageStream.Size));
IdTcpClient1.WriteStream(MyImageStream); // AWriteByteCount=False

procedure TForm1.IdTcpServer1JPEGCommand(ASender: TIdCommand);
var
  Size: Integer;
  Strm: TMemoryStream;
begin   
  ...
  Size := StrToInt(ASender.Params[0]);
  Strm := TMemoryStream.Create;
  try
    if Size > 0 then
      ASender.Thread.Connection.ReadStream(Strm, Size, False); // AWriteByteCount=True not expected
    ...
  finally
    Strm.Free;
  end;
  ...
end;
于 2014-01-01T19:18:15.373 回答
0

那么服务器如何处理这个事件

那么你真正想学什么?你的实际问题是什么?

  • 如果您想知道您的服务器将如何运行 - 那么只需运行您的程序,看看会发生什么。
  • 如果您想知道如何设计您的服务器和客户端,以便客户端可以将图片上传到服务器 - 然后问这个问题。

我认为正确的做法是添加带有两个参数的命令“picture-upload”:一个整数标记和一个 jpeg 流。

当服务器回复cmd1命令时,如果需要,它会生成并附加一个唯一的整数令牌,要求客户端上传屏幕截图。

当客户端收到这个回复时,它会解析它,如果找到令牌 - 将发出另一个命令,一个专门设计的“图片上传#12345”(其中 12345 替换为实际令牌值),然后是图片本身. 然后,服务器将使用令牌值来了解哪个客户端以及上传的原因。

PS。虽然我个人认为你最好只使用标准化的 HTTP REST 而不是制作自己的不兼容协议。

于 2014-01-01T19:20:25.913 回答