indy10的idHttpServer发送流

indy10的idHttpServer发送流

先看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
procedure TIdIOHandler.Write(AStream: TStream; ASize: TIdStreamSize = 0;
  AWriteByteCount: Boolean = FALSE);
var
  LBuffer: TIdBytes;
  LStreamPos: TIdStreamSize;
  LBufSize: Integer;
  // LBufferingStarted: Boolean;
begin
  if ASize < 0 then begin //"-1" All from current position
    LStreamPos := AStream.Position;
    ASize := AStream.Size - LStreamPos;
                                  
    AStream.Position := LStreamPos;
  end
  else if ASize = 0 then begin //"0" ALL
    ASize := AStream.Size;
    AStream.Position := 0;
  end;
  //else ">0" number of bytes
 
  // RLebeau 3/19/2006: DO NOT ENABLE WRITE BUFFERING IN THIS METHOD!
  //
  // When sending large streams, especially with LargeStream enabled,
  // this can easily cause "Out of Memory" errors.  It is the caller's
  // responsibility to enable/disable write buffering as needed before
  // calling one of the Write() methods.
  //
  // Also, forcing write buffering in this method is having major
  // impacts on TIdFTP, TIdFTPServer, and TIdHTTPServer.
 
  if AWriteByteCount then begin
    if LargeStream then begin
      Write(Int64(ASize));
    end else begin
      {$IFDEF STREAM_SIZE_64}
      if ASize > High(Integer) then begin
        raise EIdIOHandlerRequiresLargeStream.Create(RSRequiresLargeStream);
      end;
      {$ENDIF}
      Write(Int32(ASize));
    end;
  end;
 
  BeginWork(wmWrite, ASize);
  try
    SetLength(LBuffer, FSendBufferSize);
    while ASize > 0 do begin
      LBufSize := IndyMin(ASize, Length(LBuffer));
      // Do not use ReadBuffer. Some source streams are real time and will not
      // return as much data as we request. Kind of like recv()
      // NOTE: We use .Size - size must be supported even if real time
      LBufSize := TIdStreamHelper.ReadBytes(AStream, LBuffer, LBufSize);
      if LBufSize <= 0 then begin
        raise EIdNoDataToRead.Create(RSIdNoDataToRead);
      end;
      Write(LBuffer, LBufSize);
      // RLebeau: DoWork() is called in WriteDirect()
      //DoWork(wmWrite, LBufSize);
      Dec(ASize, LBufSize);
    end;
  finally
    EndWork(wmWrite);
    LBuffer := nil;
  end;
end;

  

1
2
3
const
  GRecvBufferSizeDefault = 32 * 1024;
  GSendBufferSizeDefault = 32 * 1024;

  如果流数据大于32K,会分成多包发送,每包最大32K。

posted @   delphi中间件  阅读(1424)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2017-01-12 SUPEROBJECT序列数据集为JSON
点击右上角即可分享
微信分享提示