简体   繁体   English

我一直从TClientSocket接收0字节

[英]I keep receiving 0 byte from TClientSocket

Using DbgView, i saw that after i receive a Stream, the server then receives 0 bytes like more than 100 times, what is this ? 使用DbgView,我看到收到Stream后,服务器接收0字节超过100次,这是什么? this is new to me, i never saw this happening. 这对我来说是新的,我从来没有看到过这种情况。

i personally have a feeling it is a client-side issue, could it ? 我个人觉得这是一个客户端问题,不是吗?

this is how i receive the stream server-side : 这是我收到流服务器端的方式

  FMemStream := Socket.ReceiveStream(FMemStreamSize, cbUpdateStreamProgBar);
    try
      doClientReadStreamEnd;
    finally
      FMemStream.Free;
      FInStreamMode := False; // we're not in stream mode anymore
    end;

function TCustomWinSocketHelpher.ReceiveStream(StreamLen: Integer; Callback: TUpdateProgBarProc): TMemoryStream;
const
  ChunkSize = 4096; // 4kb
var
  PData: PByte;
  ReadAmount: Integer;
begin
  Result := TMemoryStream.Create;
  GetMem(PData, StreamLen);
  try
    while StreamLen > 0 do
    begin
      ReadAmount := ReceiveBuf(PData^, ChunkSize);
      if (ReadAmount > 0) then
      begin
        Result.Write(PData^, ReadAmount);
        Callback(ReadAmount); // update gui
        Inc(PData^, ReadAmount); // update PData current position
        Dec(StreamLen, ReadAmount); // update loop condition
      end;
    end;
  finally
    FreeMem(PData);
  end;
end;

on client-side, this is how i send stream : 在客户端,这是我发送流的方式

FClientSocket.Socket.SendStreamEx(RemoteProcedureCalls.Stream);

procedure TCustomWinSocketHelpher.SendStreamEx(Stream: TStream);
begin
  Stream.Seek(0, TSeekOrigin.soBeginning);
  SendStream(Stream);
end;

Here's a photo of how it looks, it should not continue sending after line 5 . 这是一张它看起来如何的照片,它不应该继续在 5 之后发送

在此输入图像描述

When ReceiveBuf() returns 0, it means the socket has been disconnected by the other party. ReceiveBuf()返回0时,表示套接字已被另一方断开。 You are not handling that condition, so you keep looping, getting back 0 again and again. 你没有处理这个条件,所以你继续循环,一次又一次地回到0。 Any value less than 1 is a failed read and needs to be treated as such. 任何小于1的值都是读取失败,需要这样处理。 If ReceiveBuf() returns -1, an actual read error occurred, but that result can only be returned if the error was WSAEWOULDBLOCK , which is not fatal, or you have an OnError event handler assigned that is setting ErrorCode := 0 . 如果ReceiveBuf()返回-1,则发生实际的读取错误,但只有在错误是WSAEWOULDBLOCK才会返回该结果,这不是致命的,或者您指定了设置ErrorCode := 0OnError事件处理程序。 Otherwise, ReceiveBuf() would raise an ESocketError exception on a real socket error. 否则, ReceiveBuf()会在实际套接字错误上引发ESocketError异常。

Try this: 尝试这个:

function TCustomWinSocketHelpher.ReceiveStream(StreamLen: Integer; Callback: TUpdateProgBarProc): TMemoryStream;
const
  ChunkSize = 4096; // 4kb
var
  PData: PByte;
  ReadAmount: Integer;
begin
  Result := TMemoryStream.Create;
  try
    GetMem(PData, ChunkSize);
    try
      while StreamLen > 0 do
      begin
        ReadAmount := ReceiveBuf(PData^, Min(ChunkSize, StreamLen));
        if ReadAmount < 0 then
        begin
          if WSAGetLastError() = WSAEWOULDBLOCK then
            Continue;
          // an OnError event handler must have disabled an exception being raised
          Exit;
        end;
        if ReadAmount = 0 then
        begin
          // socket disconnected
          raise Exception.Create(''); // or just Exit if you don't mind that the expected data is incomplete
        end;
        Result.WriteBuffer(PData^, ReadAmount);
        Callback(ReadAmount); // update gui
        Dec(StreamLen, ReadAmount); // update loop condition
      end;
    finally
      FreeMem(PData);
    end;
  except
    Result.Free;
    raise;
  end;
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM