Indy 10 IdTCPSever Readbytes加扰数据

时间:2013-09-25 13:30:14

标签: delphi sockets indy10

我试图在Delphi 2007中使用Indy10 ReadBytes()来读取格式化为[#bytes] \ r \ n的一系列数据段的大量下载,其中#bytes表示字节数。我的算法是:

  1. 使用ReadBytes()获取[#] \ r \ n文本,通常为10个字节。
  2. 使用ReadBytes()获取指定的#data bytes。
  3. 如果需要处理更多数据段,请转到步骤1,即#为负数。
  4. 这很有效,但我经常在步骤1中没有得到预期的文本。这是330个成功数据段之后的简短示例:

    从上一步2 ReadBytes()收到的数据。注意嵌入式步骤1 [-08019] \ r \ n文本。

    Line|A033164|B033164|C033164|D033164|E033164|F033164|G033164|H033164|EndL\r|Begin 
    Line|A033165|B033165|C033165|D033165|E033165|F033165|G033165|H033165|EndL\r|Begin 
    Line|A033166|B033166|C033166|D033166|E033166|F033166|G033166|H033166|EndL\r[-08019]
    

    \ r \ N |开始     线| A033167 | B033167 | C033167 | D033167 | E033167 | F033167 | G033167 | H033167 | ENDL \ r |开始     生产线| A033168 | B033168 | C033168 | D033168 | E033168 | F033168 | G033168 | H033168 | EndL \ r |开始

    WireShark捕获的套接字数据。

    0090 30 33 33 31 36 36 7c 42 30 33 33 31 36 36 7c 43 033166|B033166|C
    00a0 30 33 33 31 36 36 7c 44 30 33 33 31 36 36 7c 45 033166|D033166|E
    00b0 30 33 33 31 36 36 7c 46 30 33 33 31 36 36 7c 47 033166|F033166|G
    00c0 30 33 33 31 36 36 7c 48 30 33 33 31 36 36 7c 45 033166|H033166|E
    00d0 6e 64 4c 0d ndL.
    

    没有。时间源目标协议长度信息

    2837 4.386336000 000.00.247.121 000.00.172.17 TCP 1514 40887 > 57006 [ACK] Seq=2689776 Ack=93 Win=1460 Len=1460
    Frame 2837: 1514 bytes on wire (12112 bits), 1514 bytes captured (12112 bits) on interface 0
    Ethernet II, Src: Cisco_60:4d:bf (e4:d3:f1:60:4d:bf), Dst: Dell_2a:78:29 (f0:4d:a2:2a:78:29)
    Internet Protocol Version 4, Src: 000.00.247.121 (000.00.247.121), Dst: 000.00.172.17 (000.00.172.17)
    Transmission Control Protocol, Src Port: 40887 (40887), Dst Port: 57006 (57006), Seq: 2689776, Ack: 93, Len: 1460
    Data (1460 bytes)
    
    0000 5b 2d 30 38 30 31 39 5d 0d 0a 7c 42 65 67 69 6e [-08019]..|Begin
    0010 20 4c 69 6e 65 7c 41 30 33 33 31 36 37 7c 42 30 Line|A033167|B0
    0020 33 33 31 36 37 7c 43 30 33 33 31 36 37 7c 44 30 33167|C033167|D0
    0030 33 33 31 36 37 7c 45 30 33 33 31 36 37 7c 46 30 33167|E033167|F0
    

    有谁知道为什么会这样?感谢

    更多信息。我们从单个线程读取套接字,并且在读取时不调用Connected()。这是相关的代码段:

    AClientDebugSocketContext.Connection.Socket.ReadBytes(inBuffer,byteCount,True);
    numBytes := Length(inBuffer);
    Logger.WriteToLogFile(BytesToString: '+BytesToString(inBuffer,0,numBytes),0);
    Move(inBuffer[0], Pointer(Integer(Buffer))^, numBytes);
    

1 个答案:

答案 0 :(得分:0)

您描述的嵌入式数据,尤其是在随机时间,通常会在您同时从多个线程中的同一套接字读取而没有它们之间充分同步时发生。一个线程可以接收一部分传入数据,另一个线程可以接收另一部分数据,并且它们最终以错误的顺序将它们的数据存储在InputBuffer中。由于你没有提供任何代码,很难确定你的问题是否存在。最好的选择是确保你永远不会从多个线程中的同一个套接字读取。这包括对Connected()的任何调用,因为它在内部执行读操作。你应该在一个线程中完成所有的阅读。如果这不是一个选项,那么至少用一些线程间锁定来封装你的套接字I / O,例如关键部分或互斥锁。

更新:您正在通过自己的TIdContext变量访问AClientDebugSocketContext个对象。那个代码到底在哪里使用?如果它不在服务器的OnConnectOnDisconnectOnExecuteOnException事件的上下文中,那么您将从多个线程的同一个套接字读取,因为{ {1}}在对TIdTCPServer对象的Connected()事件的调用之间内部调用OnExecute(执行读取)。