Error: Send buffer full, try again later lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Awesome Programmer · 2017-04-14 15:26 Hello, I wrote a min program that is suppose to send files, but it is telling me, "Error: Send buffer full, try again later." I am not sure why. Here is the code that sends file. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const  BufferSize = 1024;var  Fs: TFileStream;  TotalCount: Integer;  Buffer: Pointer;  BytesToRead: Integer;  begin  Fs := TFileStream.Create('pathtoyourfile', fmOpenRead or fmshareDenyWrite);  try    TotalCount := 0;    GetMem(Buffer, BufferSize);    repeat      if TotalCount + BufferSize > Fs.Size then        BytesToRead := FS.Size - TotalCount      else        BytesToRead := BufferSize;      Fs.Read(Buffer^, BytesToRead);      aSocket.Send(Buffer, BufferSize);      TotalCount := TotalCount + BytesToRead;    until TotalCount >= FS.Size;    FreeMem(Buffer);  finally    Fs.Free;  end;                end; Any hints or help will be greatly appreciated. ---------------------------------------------------------------------- wp · 2017-04-14 15:43 Nobody can help you if you don't tell us what FCon is. ---------------------------------------------------------------------- Awesome Programmer · 2017-04-14 15:52 Sorry.... FCon is actually the socket. I corrected the code above. ---------------------------------------------------------------------- howardpc · 2017-04-14 16:14 Does it help if you change the repeat until condition to this? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i until (TotalCount >= FS.Size) or (BytesToRead < BufferSize); ---------------------------------------------------------------------- Awesome Programmer · 2017-04-17 14:07 I am still getting the same error - Error: Send Buffer full try again later - by the server or the host. ---------------------------------------------------------------------- balazsszekely · 2017-04-17 14:58 What is your platform? Lazarus/FPC version? What component? LNet, Indy, Syanpse? It looks like you copied this code: http://forum.lazarus.freepascal.org/index.php/topic,35272.msg233478.ht ml#msg233478 which was a hypothetical example, I don't think will work in real life, however you can find working code below, if lnet is what are you after: http://forum.lazarus.freepascal.org/index.php/topic,35272.msg23 3630.html#msg233630 ---------------------------------------------------------------------- Remy Lebeau · 2017-04-17 16:35 Quote from: reltek on April 14, 2017, 05:26:24 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i aSocket.Send(Buffer, BufferSize); Using BufferSize when calling Send() is wrong.  You need to use BytesToRead instead.  Actually, you should be using the return value of TFileStream.Read() instead, eg: Code: [Select]const   BufferSize = 1024; var   Fs: TFileStream;   Buffer: Pointer;   BytesRead: Integer;  begin   Fs := TFileStream.Create('pathtoyourfile', fmOpenRead or fmshareDenyWrite);   try     GetMem(Buffer, BufferSize);     try       repeat         BytesRead := Fs.Read(Buffer^, BufferSize);         if BytesRead <= 0 then Break;         aSocket.Send(Buffer, BytesRead);       until False;     finally       FreeMem(Buffer);     end;   finally     Fs.Free;   end;                  end; ---------------------------------------------------------------------- Awesome Programmer · 2017-04-19 15:06 Quote from: Remy Lebeau on April 17, 2017, 06:35:14 pmQuote from: reltek on April 14, 2017, 05:26:24 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i aSocket.Send(Buffer, BufferSize); Using BufferSize when calling Send() is wrong.  You need to use BytesToRead instead.  Actually, you should be using the return value of TFileStream.Read() instead, eg: Code: [Select]const   BufferSize = 1024; var   Fs: TFileStream;   Buffer: Pointer;   BytesRead: Integer;  begin   Fs := TFileStream.Create('pathtoyourfile', fmOpenRead or fmshareDenyWrite);   try     GetMem(Buffer, BufferSize);     try       repeat         BytesRead := Fs.Read(Buffer^, BufferSize);         if BytesRead <= 0 then Break;         aSocket.Send(Buffer, BytesRead);       until False;     finally       FreeMem(Buffer);     end;   finally     Fs.Free;   end;                  end; Hi Remy. Thank you for that awesome sample code. I was wondering if you could also show me how you would do the receiving of the file. I just want to make sure I am doing it right. Thank you. Here is my code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i constBufferSize = 1024;var  Fs: TFileStream;  Buffer: Pointer;  ReadBytes:Integer;  Fnet : TLConnection;begin fs := TFileStream.Create('local file name', fmCreate);   try   GetMem(Buffer, BufferSize);      while True do   begin       ReadBytes := fNet.Get(Buffer, BufferSize);              if (ReadBytes = 0) then            break       else            fs.write(Buffer, ReadBytes);              Application.ProcessMessages;       Sleep(1);   end;  Finally   fs.free;   freemem(Buffer);  end;end; ---------------------------------------------------------------------- Remy Lebeau · 2017-04-19 17:58 Quote from: reltek on April 19, 2017, 05:06:56 pmI was wondering if you could also show me how you would do the receiving of the file. I just want to make sure I am doing it right. The sender needs to indicate when the file is finished so the receiver knows when to stop reading.  There are only two ways to do that reliably - close the connection at the end of the file, or else send the file size before sending the file data.  Your current code expects the first, but the second is preferred instead, eg: Code: [Select]procedure sendRaw(Fnet: TLConnection; var Buffer; BufferSize: Integer); var   Ptr: PByte;   NumSent: Integer; begin   Ptr := PByte(@Buffer);   while BufferSize > 0 do   begin     NumSent := Fnet.Send(Ptr, BufferSize);     if NumSent <= 0 then raise Exception.Create('socket send error');     Inc(Ptr, NumSent);     Dec(BufferSize, NumSent);   end; end; ... const   BufferSize = 1024; var   Fs: TFileStream;   FileSize, FileSizeTmp: Int64;   Buffer: Pointer;   BytesRead: Integer;    Fnet: TLConnection; begin   Fnet := ...;   Fs := TFileStream.Create('pathtoyourfile', fmOpenRead or fmshareDenyWrite);   try     FileSize := Fs.Size;     // you may have to find a 3rd party implementation     // of htonll(), or implement it manually...     FileSizeTmp = htonll(FileSizeTmp);     sendRaw(Fnet, FileSizeTmp, sizeof(FileSizeTmp));     if FileSize > 0 then     begin       GetMem(Buffer, BufferSize);       try         repeat           if FileSize > BufferSize then             BytesRead := BufferSize           else             BytesRead := Integer(FileSize);           BytesRead := Fs.Read(Buffer^, BytesRead);           if BytesRead <= 0 then raise Exception.Create('file read error');           sendRaw(Fnet, Buffer, BytesRead);           Dec(FileSize, BytesRead);         until FileSize = 0;       finally         FreeMem(Buffer);       end;     end;   finally     Fs.Free;   end;                  end; Code: [Select]procedure readRaw(Fnet: TLConnection; var Buffer; BufferSize: Integer); var   Ptr: PByte;   NumRead: Integer; begin   Ptr := PByte(@Buffer);   while BufferSize > 0 do   begin     NumRead := Fnet.Get(Ptr, BufferSize);     if NumRead <= 0 then raise Exception.Create('socket read error');     Inc(Ptr, NumRead);     Dec(BufferSize, NumRead);   end; end; ... const   BufferSize = 1024; var   Fs: TFileStream;   FileSize: Int64;   Buffer: Pointer;   ReadBytes: Integer;   Fnet: TLConnection; begin   Fnet := ...;   Fs := TFileStream.Create('local file name', fmCreate);   try     readRaw(Fnet, FileSize, sizeof(FileSize));     // you may have to find a 3rd party implementation     // of ntohll(), or implement it manually...     FileSize := ntohll(FileSize);     if FileSize > 0 then     begin       GetMem(Buffer, BufferSize);       try         repeat           if FileSize > BufferSize then             ReadBytes := BufferSize           else             ReadBytes := Integer(FileSize);           readRaw(Fnet, Buffer, ReadBytes);           Fs.WriteBuffer(Buffer^, ReadBytes);           Dec(FileSize, ReadBytes);         until FileSize = 0;       finally         FreeMem(Buffer);       end;     end;   finally     Fs.free;   end; end; ---------------------------------------------------------------------- Awesome Programmer · 2017-04-19 20:38 Thank you so much, Remi.