Translated my chat from UDP to TCP and faced with the fact that data packets on the way to the server are glued together and vice versa from server to client. I could not compile the problem solving algorithm, I could not find any examples and information either.

procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); Var MemoryBuffer: string; i, p: integer; MemoryChange: string; login, password, UserSender, UserClientMessage, TextMessage, lastUserConnect: string; NewUser: boolean; begin MemoryBuffer:= Socket.ReceiveText; if Copy(MemoryBuffer,1,9) = '[Request]' then//ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π² ΠΏΡ€ΠΈΡˆΠ΅Π΄ΡˆΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… begin ...//ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…(ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚, Ρ‚Π°ΠΊ ΠΈ сСрвСр ΠΏΠΎ Ρ‚Π°ΠΊΠΎΠΌΡƒ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡƒ) end; 
  • one
    What exactly do you want to solve, what's the problem? In TCP, it is usually enough to write your own headers for packets β€” length + body. You can also disable the Nagel algorithm so that TCP does not wait for more packets before sending, but sends it immediately. - Kromster
  • I do not understand how this is implemented. The fact that words can be sent in fragments, I get into the buffer, but I don’t understand how to implement it in the code. - mNT
  • ServerSocket1ClientRead (Sender: TObject; Socket: TCustomWinSocket); Var MemoryBuffer: string; i, p: integer; MemoryChange: string; login, password, UserSender, UserClientMessage, TextMessage, lastUserConnect: string; NewUser: boolean; begin MemoryBuffer: = Socket.ReceiveText; if Copy (MemoryBuffer, 1,9) = '[Request]' then // Here I check the text for commands and stuff that the client asks to execute. (from the client also reads (read)) - mNT
  • Added to the question code - mNT
  • You are absolutely right about the problem of splitting and gluing packages! With (especially) intensive exchange, it can be arbitrarily broken and glued together, the only thing is that the sending / receiving sequence does not change. In the "bare TCP" text can not work, you need to work with a sequence of bytes with a header. For example: github.com/kami-soft/SimpleTCPComponents Relatively detailed answer: ru.stackoverflow.com/a/529962/192901 - kami

1 answer 1

Here is the code, but only indie, but there are not many differences from SocketServer (the name of the functions) - the essence will be the same for you ... The packet is transmitted by the view: The first byte is the id package (2-3-4-XX bytes are possible, how many types you need) The second and third bytes (I need messages in several dozen KB) - packet size.

 Var b:Byte; begin while Sock.IOHandler.InputBuffer.Size>0 do Begin b:=Sock.IOHandler.ReadByte; // Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Ρ‹Π²Π°Π΅ΠΌ \ распаковываСм Π±Π°ΠΉΡ‚ - Ссли Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ SocketStream.Write(b,1); if (pSize=0)and(SocketStream.Size>2) then Begin SocketStream.Position:=0; SocketStream.Read(pOpcode,1); SocketStream.Read(pSize,4); SocketStream.Position:=SocketStream.Size; End; if (pSize>0)and(SocketStream.Size=pSize) then Begin // << ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° вашСго "сообщСния(ΠΏΠ°ΠΊΠ΅Ρ‚Π°)" >>; pSize := 0; SocketStream.clear; End; End; end; SocketStream - TMemoryStream - Π±ΡƒΡ„Π΅Ρ€ для сборки ΠΏΠ°ΠΊΠ΅Ρ‚Π°. pSize - Word - Π Π°Π·ΠΌΠ΅Ρ€ собираСмого ΠΏΠ°ΠΊΠ΅Ρ‚Π°(ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΆΠ΄Π΅ΠΌ) pOpCode - Byte - Π’ΠΈΠΏ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚Π°. 

For everyone who is going to criticize the assembly of a package by byte - I need it, because my code uses streaming compression and encryption, with an input of just 1 byte .. The author of the question is free to expect at least the entire packet if it does not need it (processing each byte separately). The code to wait for the entire package is not difficult to remake.