LiveOrDevTrying / Tcp.NET

Tcp.NET provides an easy-to-use and customizable Tcp Server and Tcp Client. The server is created using a TcpListener. The server and client can be used for non-SSL or SSL connections and authentication (including client and server ssl certification validation) is provided for identifying the clients connected to your server. Both client and server are created in .NET Standard and use async await functionality.
Apache License 2.0
42 stars 10 forks source link

EndOfLineBytes has an issue #10

Closed 604980670 closed 6 months ago

604980670 commented 6 months ago

There is a fatal bug when using this plugin to transfer byte[] that is, the separator is easy to confuse with the content, can you propose a new solution, that is, put the length of the content in the header when sending, and get it according to the length when intercepting the content

LiveOrDevTrying commented 6 months ago

Hi @604980670 ,

Tcp.NET doesn't modify the header and instead relies on .NET's Socket class to manage header. The RFC is here: https://www.ietf.org/rfc/rfc793.txt. To remain consistent with other TCP client/servers in other frameworks, it would be best not to modify something like the standard header and its implementation.

Tcp is a persistent connection and data flows the .NET framework as a stream. Every tick, the data received on the stream is dumped into an in-memory buffer and parsed for the end of line bytes. If the end of line bytes are found, the in-memory buffer is clipped and the buffered byte array is emit as an event. It's standard practice to use some end of line byte or byte array to signify end of message for raw Tcp / Udp connections, and in your case, it appears the recommended "\r\n" (carriage return new line) is a conflict.

There are a couple options that can help you without modifying the Tcp protocol:

  1. Base64 encode your byte array and send it as a string, and then on the client, decode from Base64 back into a byte array. Base64 encoding will change your byte array into an easily transmissible string but will add very minimal processing on your client and server to encode / code from Base64 to byte array.
  2. You can change the end of line byte array to something that does not conflict with your data, for example, new byte[] { 3 }. Byte 3 is not regularly used. However, Tcp.NET uses Byte 3 as a Disconnect request byte to alert the client / server of a requested disconnection for a client/server. To use byte[] { 3 } as your end of line byte array, you will need to set useDisconnectBytes in the constructor to false, or change disconnectBytes byte array to something that won't conflict - I imagine this will likely be the same problem. I would recommend setting disconnectBytes to false, unless disconnect request notification is a requirement for your project - disconnect request is one of the benefits of using Tcp.NET - in which case the other solutions might work better.
  3. You can use a different protocol like Websockets - there is a brother / sister package with Tcp.NET for Websockets I built called WebsocketsSimple here https://github.com/LiveOrDevTrying/WebsocketsSimple. It follows the exact same patterns for implementation as Tcp.NET and would be very easy to swap out. The RFC for Websockets is here: https://datatracker.ietf.org/doc/html/rfc6455. Websockets are a protocol built on top of standard Tcp that includes end of message detection for binary messages and disconnect notification and is supported by any framework following the RFC's direction.

Please let me know if this helps, if you have any questions, and or anything I can assist with.

Thank you again for using Tcp.NET! Rob

604980670 commented 6 months ago

Thanks