Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. C# TCP networkstreem problem

C# TCP networkstreem problem

Scheduled Pinned Locked Moved C#
helpcsharpsysadmindata-structuresxml
5 Posts 4 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Titok Levi
    wrote on last edited by
    #1

    Hi. I got a server and a client application. Server sends bytes to client in TCP. But the problem is that it's "too fast" I mean in a way. For be more specific. I have objects of a class (in a List) in the server side, I format that to xml string, and then format the string to bytes and send this byte array. //Client:

    //...
    NetworkStream = new NetworkStream(SocketClient);
    while (ListOfObjectToSendOut.Count > 0) //For example 5 times, cause i have 5 Object in my List
    {
    //...Formating to XML string
    //...Convert string to byteArray (BytesToSend)

    NetworkStream.Write(BytesToSend, 0, BytesToSend.Length);
    NetworkStream.Flush();
     
    //I have to take this here, BUT I DONT WANT THAT
    Thread.Sleep(100);
    

    }

    //Server:

    TcpClient myClient = new TcpClient("localhost", 8000);

    NetworkStream NetworkStream = myClient.GetStream();
    byte[] bytes = new byte[3000];
    while (true)
    {
    int IncomingByteLength = NetworkStream.Read(incomingBytes, 0, 3000); //VÁR bejövő adatra

    //Convert incomingBytes to (XML) string
    //string to MyClass
    

    }

    You can ask, what's my problem?. Let's say that the Object I want to send is 150 bytes long. And I want to send out 5 Object. My problem that i need to happen this in an order like this: Write 150 byte Read 150 byte (and than "unformat" it) Write 150 byte Read 150 byte (and than "unformat" it) and so on. With this way I could unfomate the 150 byte in the Client side. BUT!!! In a real world it will write out 150 byte and 150 byte again and so on and THAN the Client will Read 450 or 600 or 750 bytes. It is imponderable. And I CAN NOT unformat 300 or 450 ... to my Object. So the Flush doesn't flush it (I read in msdn that it is ok, cause flush wont do anything with the networkstream)So the problem is that the Server sends out 150 bytes and send out the next 150 bytes so fast that the Client will read those together (for example 300 bytes), which is not good. I need to READ THIS "PACKAGES" SEPARATE in the client side. - I can solve this to write a Thread.Sleep(100) but i dont want to do that, It would be to slow! - I can solve this proble using UDP, but i dont want to use UDP. - I could solve this porblem with a a solution like: Take a sign byte after every 150 byte, and seperate in the client side by that sign. And then format the bytes back. But I dont want to do that. - I tried Socket.NoDelay doesn't help - I tired close and dispose and than make it

    L 0 T 3 Replies Last reply
    0
    • T Titok Levi

      Hi. I got a server and a client application. Server sends bytes to client in TCP. But the problem is that it's "too fast" I mean in a way. For be more specific. I have objects of a class (in a List) in the server side, I format that to xml string, and then format the string to bytes and send this byte array. //Client:

      //...
      NetworkStream = new NetworkStream(SocketClient);
      while (ListOfObjectToSendOut.Count > 0) //For example 5 times, cause i have 5 Object in my List
      {
      //...Formating to XML string
      //...Convert string to byteArray (BytesToSend)

      NetworkStream.Write(BytesToSend, 0, BytesToSend.Length);
      NetworkStream.Flush();
       
      //I have to take this here, BUT I DONT WANT THAT
      Thread.Sleep(100);
      

      }

      //Server:

      TcpClient myClient = new TcpClient("localhost", 8000);

      NetworkStream NetworkStream = myClient.GetStream();
      byte[] bytes = new byte[3000];
      while (true)
      {
      int IncomingByteLength = NetworkStream.Read(incomingBytes, 0, 3000); //VÁR bejövő adatra

      //Convert incomingBytes to (XML) string
      //string to MyClass
      

      }

      You can ask, what's my problem?. Let's say that the Object I want to send is 150 bytes long. And I want to send out 5 Object. My problem that i need to happen this in an order like this: Write 150 byte Read 150 byte (and than "unformat" it) Write 150 byte Read 150 byte (and than "unformat" it) and so on. With this way I could unfomate the 150 byte in the Client side. BUT!!! In a real world it will write out 150 byte and 150 byte again and so on and THAN the Client will Read 450 or 600 or 750 bytes. It is imponderable. And I CAN NOT unformat 300 or 450 ... to my Object. So the Flush doesn't flush it (I read in msdn that it is ok, cause flush wont do anything with the networkstream)So the problem is that the Server sends out 150 bytes and send out the next 150 bytes so fast that the Client will read those together (for example 300 bytes), which is not good. I need to READ THIS "PACKAGES" SEPARATE in the client side. - I can solve this to write a Thread.Sleep(100) but i dont want to do that, It would be to slow! - I can solve this proble using UDP, but i dont want to use UDP. - I could solve this porblem with a a solution like: Take a sign byte after every 150 byte, and seperate in the client side by that sign. And then format the bytes back. But I dont want to do that. - I tried Socket.NoDelay doesn't help - I tired close and dispose and than make it

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Dataflow control and message separation are important aspects of all serial communication. There are a couple of solutions: 1. keep the consumer in charge, i.e. let the consumer ask for specific data, only then the producer delivers said data, and finally the consumer reads and processes it. Pro: is simple Con: slow-down due to back-and-forth conversation 2. choose a data format that allows for message separation at the receiver side; e.g. insert a unique character (not always easy or even possible, may require an escape mechanism, etc); or use a "protocol" that predicts the useful length of the message (length+content, as in Pascal strings). So now the producer can produce many messages, they all are separable. Pro: one-way communication, no slow-down Con: somewhat more complex as the consumer may read too much data, needs to process what amounts to one message, and then somehow recirculate whatever extra data he already got. Kind of a push back, as in LALR parsers. Easiest way is by copying the remaining data to the beginning of the receiving buffer; there are schemes without copying, a round-robin buffer would be one of them. You may want or need a real dataflow control on top of (2), as it does not solve the consumer overrun by producer situation. :)

      Luc Pattyn


      Local announcement (Antwerp region): Lange Wapper? Neen!


      1 Reply Last reply
      0
      • T Titok Levi

        Hi. I got a server and a client application. Server sends bytes to client in TCP. But the problem is that it's "too fast" I mean in a way. For be more specific. I have objects of a class (in a List) in the server side, I format that to xml string, and then format the string to bytes and send this byte array. //Client:

        //...
        NetworkStream = new NetworkStream(SocketClient);
        while (ListOfObjectToSendOut.Count > 0) //For example 5 times, cause i have 5 Object in my List
        {
        //...Formating to XML string
        //...Convert string to byteArray (BytesToSend)

        NetworkStream.Write(BytesToSend, 0, BytesToSend.Length);
        NetworkStream.Flush();
         
        //I have to take this here, BUT I DONT WANT THAT
        Thread.Sleep(100);
        

        }

        //Server:

        TcpClient myClient = new TcpClient("localhost", 8000);

        NetworkStream NetworkStream = myClient.GetStream();
        byte[] bytes = new byte[3000];
        while (true)
        {
        int IncomingByteLength = NetworkStream.Read(incomingBytes, 0, 3000); //VÁR bejövő adatra

        //Convert incomingBytes to (XML) string
        //string to MyClass
        

        }

        You can ask, what's my problem?. Let's say that the Object I want to send is 150 bytes long. And I want to send out 5 Object. My problem that i need to happen this in an order like this: Write 150 byte Read 150 byte (and than "unformat" it) Write 150 byte Read 150 byte (and than "unformat" it) and so on. With this way I could unfomate the 150 byte in the Client side. BUT!!! In a real world it will write out 150 byte and 150 byte again and so on and THAN the Client will Read 450 or 600 or 750 bytes. It is imponderable. And I CAN NOT unformat 300 or 450 ... to my Object. So the Flush doesn't flush it (I read in msdn that it is ok, cause flush wont do anything with the networkstream)So the problem is that the Server sends out 150 bytes and send out the next 150 bytes so fast that the Client will read those together (for example 300 bytes), which is not good. I need to READ THIS "PACKAGES" SEPARATE in the client side. - I can solve this to write a Thread.Sleep(100) but i dont want to do that, It would be to slow! - I can solve this proble using UDP, but i dont want to use UDP. - I could solve this porblem with a a solution like: Take a sign byte after every 150 byte, and seperate in the client side by that sign. And then format the bytes back. But I dont want to do that. - I tried Socket.NoDelay doesn't help - I tired close and dispose and than make it

        0 Offline
        0 Offline
        0x3c0
        wrote on last edited by
        #3

        Something which you might find useful is serializing all of your objects to the Stream and deserializing them in order. If you don't want to do that, then perhaps you could repeatedly read the data into a buffer of 150 bytes; as a heads-up, this implies that the data length is known by both sides.

        OSDev :)

        1 Reply Last reply
        0
        • T Titok Levi

          Hi. I got a server and a client application. Server sends bytes to client in TCP. But the problem is that it's "too fast" I mean in a way. For be more specific. I have objects of a class (in a List) in the server side, I format that to xml string, and then format the string to bytes and send this byte array. //Client:

          //...
          NetworkStream = new NetworkStream(SocketClient);
          while (ListOfObjectToSendOut.Count > 0) //For example 5 times, cause i have 5 Object in my List
          {
          //...Formating to XML string
          //...Convert string to byteArray (BytesToSend)

          NetworkStream.Write(BytesToSend, 0, BytesToSend.Length);
          NetworkStream.Flush();
           
          //I have to take this here, BUT I DONT WANT THAT
          Thread.Sleep(100);
          

          }

          //Server:

          TcpClient myClient = new TcpClient("localhost", 8000);

          NetworkStream NetworkStream = myClient.GetStream();
          byte[] bytes = new byte[3000];
          while (true)
          {
          int IncomingByteLength = NetworkStream.Read(incomingBytes, 0, 3000); //VÁR bejövő adatra

          //Convert incomingBytes to (XML) string
          //string to MyClass
          

          }

          You can ask, what's my problem?. Let's say that the Object I want to send is 150 bytes long. And I want to send out 5 Object. My problem that i need to happen this in an order like this: Write 150 byte Read 150 byte (and than "unformat" it) Write 150 byte Read 150 byte (and than "unformat" it) and so on. With this way I could unfomate the 150 byte in the Client side. BUT!!! In a real world it will write out 150 byte and 150 byte again and so on and THAN the Client will Read 450 or 600 or 750 bytes. It is imponderable. And I CAN NOT unformat 300 or 450 ... to my Object. So the Flush doesn't flush it (I read in msdn that it is ok, cause flush wont do anything with the networkstream)So the problem is that the Server sends out 150 bytes and send out the next 150 bytes so fast that the Client will read those together (for example 300 bytes), which is not good. I need to READ THIS "PACKAGES" SEPARATE in the client side. - I can solve this to write a Thread.Sleep(100) but i dont want to do that, It would be to slow! - I can solve this proble using UDP, but i dont want to use UDP. - I could solve this porblem with a a solution like: Take a sign byte after every 150 byte, and seperate in the client side by that sign. And then format the bytes back. But I dont want to do that. - I tried Socket.NoDelay doesn't help - I tired close and dispose and than make it

          T Offline
          T Offline
          Tr v
          wrote on last edited by
          #4

          Luc is leading you in the right direction. In my job we do lots of serial and TCP/IP connection between PC's and various devices. We use both methods he suggests but more often than not the protocols we develop have some start character and stop character to delineate the message. The characters that are meant for this purpose are hex 0x02(send transmission) and hex 0x03(end transmission). These characters work well as neither are printable characters so it is unlikely that you would be sending them in a normal message. If you really want to get picky and guarantee that the data you receive is the same as the data you sent you should be using some form of error checking such as cyclic redundancy check. If you want to do error checking I would recommend using the send/acknowledge system so that your client can let the server know if it got good data and if not it can send a negative acknowledgement to let the server know it needs to resend the data. If you always know how many bytes you are expecting you can always just read that many bytes out of your receive buffer and process them, then go back and read more bytes etc... this might be a simpler solution if you don't want to build some sort of protocol, just be sure that your buffer size is large enough that it won't overflow.

          T 1 Reply Last reply
          0
          • T Tr v

            Luc is leading you in the right direction. In my job we do lots of serial and TCP/IP connection between PC's and various devices. We use both methods he suggests but more often than not the protocols we develop have some start character and stop character to delineate the message. The characters that are meant for this purpose are hex 0x02(send transmission) and hex 0x03(end transmission). These characters work well as neither are printable characters so it is unlikely that you would be sending them in a normal message. If you really want to get picky and guarantee that the data you receive is the same as the data you sent you should be using some form of error checking such as cyclic redundancy check. If you want to do error checking I would recommend using the send/acknowledge system so that your client can let the server know if it got good data and if not it can send a negative acknowledgement to let the server know it needs to resend the data. If you always know how many bytes you are expecting you can always just read that many bytes out of your receive buffer and process them, then go back and read more bytes etc... this might be a simpler solution if you don't want to build some sort of protocol, just be sure that your buffer size is large enough that it won't overflow.

            T Offline
            T Offline
            Titok Levi
            wrote on last edited by
            #5

            Thanks everybody for the responses!!!!!!!

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups