TCP communication between C# and Java servers












2














I am trying to pass a json from C# server to Java server using TCP, problem is that the first time Java server seems to receive an empty json. Second time and onwards it works fine, see output bellow. Any ideas or suggestions are welcome, thanks in advance.



Output:



Starting server...
Waiting for a connection..
Connected!
Reading...
Received empty object
Received:
Connected!
Reading...
Received: "Request:gethotellist"
Connected!
Reading...
Received: "Request:gethotellist"


Here is the C# code snippet for sending json:



public void GetHotelList()
{
TcpClient clientSocket = new TcpClient();
clientSocket.Connect("127.0.0.1", 6767);

NetworkStream ns = clientSocket.GetStream();

string jsonRequest = "Request:gethotellist";

string jsonToSend = JsonConvert.SerializeObject(jsonRequest);

byte dataBytes = Encoding.UTF8.GetBytes(jsonToSend);

ns.Write(dataBytes, 0, dataBytes.Length);

ns.Close();
}


Java server:



public class JHotelServer
{

public static void main(String args) throws IOException
{
final int PORT = 6767;

System.out.println("Starting server...");

@SuppressWarnings("resource")
ServerSocket welcomeSocket = new ServerSocket(PORT);

System.out.println("Waiting for a connection..");

while(true)
{
try
{
Socket connectionSocket = welcomeSocket.accept();

System.out.println("Connected!");

Thread connectionThread = new Thread(new TcpConnectionManager(connectionSocket));
connectionThread.start();
}

catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
}


And here is the Tcp Communication manager:



public class TcpConnectionManager implements Runnable
{
private DataInputStream inFromDotNet;

public TcpConnectionManager(Socket socket) throws IOException
{
inFromDotNet = new DataInputStream(socket.getInputStream());
}

@Override
public void run()
{
try
{
System.out.println("Reading...");

byte rvdMsgByte = new byte[inFromDotNet.available()];

// Collecting data into byte array
for (int i = 0; i < rvdMsgByte.length; i++)
{
rvdMsgByte[i] = inFromDotNet.readByte();
}

if (rvdMsgByte.length == 0)
{
System.out.println("Received empty object");
}

// Converting collected data in byte array into String.
String rvdMsgTxt = new String(rvdMsgByte);

System.out.println("Received: " + rvdMsgTxt);
}

catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}









share|improve this question





























    2














    I am trying to pass a json from C# server to Java server using TCP, problem is that the first time Java server seems to receive an empty json. Second time and onwards it works fine, see output bellow. Any ideas or suggestions are welcome, thanks in advance.



    Output:



    Starting server...
    Waiting for a connection..
    Connected!
    Reading...
    Received empty object
    Received:
    Connected!
    Reading...
    Received: "Request:gethotellist"
    Connected!
    Reading...
    Received: "Request:gethotellist"


    Here is the C# code snippet for sending json:



    public void GetHotelList()
    {
    TcpClient clientSocket = new TcpClient();
    clientSocket.Connect("127.0.0.1", 6767);

    NetworkStream ns = clientSocket.GetStream();

    string jsonRequest = "Request:gethotellist";

    string jsonToSend = JsonConvert.SerializeObject(jsonRequest);

    byte dataBytes = Encoding.UTF8.GetBytes(jsonToSend);

    ns.Write(dataBytes, 0, dataBytes.Length);

    ns.Close();
    }


    Java server:



    public class JHotelServer
    {

    public static void main(String args) throws IOException
    {
    final int PORT = 6767;

    System.out.println("Starting server...");

    @SuppressWarnings("resource")
    ServerSocket welcomeSocket = new ServerSocket(PORT);

    System.out.println("Waiting for a connection..");

    while(true)
    {
    try
    {
    Socket connectionSocket = welcomeSocket.accept();

    System.out.println("Connected!");

    Thread connectionThread = new Thread(new TcpConnectionManager(connectionSocket));
    connectionThread.start();
    }

    catch(IOException ioe)
    {
    ioe.printStackTrace();
    }
    }
    }
    }


    And here is the Tcp Communication manager:



    public class TcpConnectionManager implements Runnable
    {
    private DataInputStream inFromDotNet;

    public TcpConnectionManager(Socket socket) throws IOException
    {
    inFromDotNet = new DataInputStream(socket.getInputStream());
    }

    @Override
    public void run()
    {
    try
    {
    System.out.println("Reading...");

    byte rvdMsgByte = new byte[inFromDotNet.available()];

    // Collecting data into byte array
    for (int i = 0; i < rvdMsgByte.length; i++)
    {
    rvdMsgByte[i] = inFromDotNet.readByte();
    }

    if (rvdMsgByte.length == 0)
    {
    System.out.println("Received empty object");
    }

    // Converting collected data in byte array into String.
    String rvdMsgTxt = new String(rvdMsgByte);

    System.out.println("Received: " + rvdMsgTxt);
    }

    catch(IOException ioe)
    {
    ioe.printStackTrace();
    }
    }
    }









    share|improve this question



























      2












      2








      2







      I am trying to pass a json from C# server to Java server using TCP, problem is that the first time Java server seems to receive an empty json. Second time and onwards it works fine, see output bellow. Any ideas or suggestions are welcome, thanks in advance.



      Output:



      Starting server...
      Waiting for a connection..
      Connected!
      Reading...
      Received empty object
      Received:
      Connected!
      Reading...
      Received: "Request:gethotellist"
      Connected!
      Reading...
      Received: "Request:gethotellist"


      Here is the C# code snippet for sending json:



      public void GetHotelList()
      {
      TcpClient clientSocket = new TcpClient();
      clientSocket.Connect("127.0.0.1", 6767);

      NetworkStream ns = clientSocket.GetStream();

      string jsonRequest = "Request:gethotellist";

      string jsonToSend = JsonConvert.SerializeObject(jsonRequest);

      byte dataBytes = Encoding.UTF8.GetBytes(jsonToSend);

      ns.Write(dataBytes, 0, dataBytes.Length);

      ns.Close();
      }


      Java server:



      public class JHotelServer
      {

      public static void main(String args) throws IOException
      {
      final int PORT = 6767;

      System.out.println("Starting server...");

      @SuppressWarnings("resource")
      ServerSocket welcomeSocket = new ServerSocket(PORT);

      System.out.println("Waiting for a connection..");

      while(true)
      {
      try
      {
      Socket connectionSocket = welcomeSocket.accept();

      System.out.println("Connected!");

      Thread connectionThread = new Thread(new TcpConnectionManager(connectionSocket));
      connectionThread.start();
      }

      catch(IOException ioe)
      {
      ioe.printStackTrace();
      }
      }
      }
      }


      And here is the Tcp Communication manager:



      public class TcpConnectionManager implements Runnable
      {
      private DataInputStream inFromDotNet;

      public TcpConnectionManager(Socket socket) throws IOException
      {
      inFromDotNet = new DataInputStream(socket.getInputStream());
      }

      @Override
      public void run()
      {
      try
      {
      System.out.println("Reading...");

      byte rvdMsgByte = new byte[inFromDotNet.available()];

      // Collecting data into byte array
      for (int i = 0; i < rvdMsgByte.length; i++)
      {
      rvdMsgByte[i] = inFromDotNet.readByte();
      }

      if (rvdMsgByte.length == 0)
      {
      System.out.println("Received empty object");
      }

      // Converting collected data in byte array into String.
      String rvdMsgTxt = new String(rvdMsgByte);

      System.out.println("Received: " + rvdMsgTxt);
      }

      catch(IOException ioe)
      {
      ioe.printStackTrace();
      }
      }
      }









      share|improve this question















      I am trying to pass a json from C# server to Java server using TCP, problem is that the first time Java server seems to receive an empty json. Second time and onwards it works fine, see output bellow. Any ideas or suggestions are welcome, thanks in advance.



      Output:



      Starting server...
      Waiting for a connection..
      Connected!
      Reading...
      Received empty object
      Received:
      Connected!
      Reading...
      Received: "Request:gethotellist"
      Connected!
      Reading...
      Received: "Request:gethotellist"


      Here is the C# code snippet for sending json:



      public void GetHotelList()
      {
      TcpClient clientSocket = new TcpClient();
      clientSocket.Connect("127.0.0.1", 6767);

      NetworkStream ns = clientSocket.GetStream();

      string jsonRequest = "Request:gethotellist";

      string jsonToSend = JsonConvert.SerializeObject(jsonRequest);

      byte dataBytes = Encoding.UTF8.GetBytes(jsonToSend);

      ns.Write(dataBytes, 0, dataBytes.Length);

      ns.Close();
      }


      Java server:



      public class JHotelServer
      {

      public static void main(String args) throws IOException
      {
      final int PORT = 6767;

      System.out.println("Starting server...");

      @SuppressWarnings("resource")
      ServerSocket welcomeSocket = new ServerSocket(PORT);

      System.out.println("Waiting for a connection..");

      while(true)
      {
      try
      {
      Socket connectionSocket = welcomeSocket.accept();

      System.out.println("Connected!");

      Thread connectionThread = new Thread(new TcpConnectionManager(connectionSocket));
      connectionThread.start();
      }

      catch(IOException ioe)
      {
      ioe.printStackTrace();
      }
      }
      }
      }


      And here is the Tcp Communication manager:



      public class TcpConnectionManager implements Runnable
      {
      private DataInputStream inFromDotNet;

      public TcpConnectionManager(Socket socket) throws IOException
      {
      inFromDotNet = new DataInputStream(socket.getInputStream());
      }

      @Override
      public void run()
      {
      try
      {
      System.out.println("Reading...");

      byte rvdMsgByte = new byte[inFromDotNet.available()];

      // Collecting data into byte array
      for (int i = 0; i < rvdMsgByte.length; i++)
      {
      rvdMsgByte[i] = inFromDotNet.readByte();
      }

      if (rvdMsgByte.length == 0)
      {
      System.out.println("Received empty object");
      }

      // Converting collected data in byte array into String.
      String rvdMsgTxt = new String(rvdMsgByte);

      System.out.println("Received: " + rvdMsgTxt);
      }

      catch(IOException ioe)
      {
      ioe.printStackTrace();
      }
      }
      }






      java c# json tcp






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 12 '18 at 16:49

























      asked Nov 12 '18 at 16:42









      Giedrius Electrum

      107210




      107210
























          1 Answer
          1






          active

          oldest

          votes


















          6














          Based on the code shown, it would be entirely expected to sometimes get an empty payload, because if the payload packets haven't arrived yet: inFromDotNet.available() will be zero.



          Basically, .available() (and equivalent) should never be used to determine anything about the content, other than "there are bytes currently buffered" (perhaps to choose between sync read and async read).



          There are two approaches commonly used here:




          • use EOF to indicate the end of the payload, i.e. read until the socket says it is closed and everything has been read; how you detect this depends on the specific socket API (for example, in .NET, it would be when Receive returns a non-positive number)

          • implement some kind of basic framing protocol


          The first option is relevant if you will only ever send one message per socket; the second option is necessary if you will be sending multiple messages per socket. A basic framing protocol could be as simple as "messages are separated by newline characters", but in many cases you may need binary-safe framing, such as a length prefix. For example, your JSON could contain newlines, which could incorrectly be interpreted as the end of a frame.



          In either case: with sockets you almost always need to read in a loop, because the data can be split over multiple packets, and/or your receive buffer size may be too small. So usually, you would loop and buffer all the payload until you detect either an EOF or the end of a frame, and only then start trying to process the content. In particular, you should not usually try to decode text until you know you have the entire thing, because multi-byte characters may span multiple "read"/"receive" calls, so: unless you're using a stateful text decoder, you may incorrectly decode such characters.



          The behaviour you're seeing would be common to almost all platforms and languages; it isn't specific to Java/C#.






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266539%2ftcp-communication-between-c-sharp-and-java-servers%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            6














            Based on the code shown, it would be entirely expected to sometimes get an empty payload, because if the payload packets haven't arrived yet: inFromDotNet.available() will be zero.



            Basically, .available() (and equivalent) should never be used to determine anything about the content, other than "there are bytes currently buffered" (perhaps to choose between sync read and async read).



            There are two approaches commonly used here:




            • use EOF to indicate the end of the payload, i.e. read until the socket says it is closed and everything has been read; how you detect this depends on the specific socket API (for example, in .NET, it would be when Receive returns a non-positive number)

            • implement some kind of basic framing protocol


            The first option is relevant if you will only ever send one message per socket; the second option is necessary if you will be sending multiple messages per socket. A basic framing protocol could be as simple as "messages are separated by newline characters", but in many cases you may need binary-safe framing, such as a length prefix. For example, your JSON could contain newlines, which could incorrectly be interpreted as the end of a frame.



            In either case: with sockets you almost always need to read in a loop, because the data can be split over multiple packets, and/or your receive buffer size may be too small. So usually, you would loop and buffer all the payload until you detect either an EOF or the end of a frame, and only then start trying to process the content. In particular, you should not usually try to decode text until you know you have the entire thing, because multi-byte characters may span multiple "read"/"receive" calls, so: unless you're using a stateful text decoder, you may incorrectly decode such characters.



            The behaviour you're seeing would be common to almost all platforms and languages; it isn't specific to Java/C#.






            share|improve this answer


























              6














              Based on the code shown, it would be entirely expected to sometimes get an empty payload, because if the payload packets haven't arrived yet: inFromDotNet.available() will be zero.



              Basically, .available() (and equivalent) should never be used to determine anything about the content, other than "there are bytes currently buffered" (perhaps to choose between sync read and async read).



              There are two approaches commonly used here:




              • use EOF to indicate the end of the payload, i.e. read until the socket says it is closed and everything has been read; how you detect this depends on the specific socket API (for example, in .NET, it would be when Receive returns a non-positive number)

              • implement some kind of basic framing protocol


              The first option is relevant if you will only ever send one message per socket; the second option is necessary if you will be sending multiple messages per socket. A basic framing protocol could be as simple as "messages are separated by newline characters", but in many cases you may need binary-safe framing, such as a length prefix. For example, your JSON could contain newlines, which could incorrectly be interpreted as the end of a frame.



              In either case: with sockets you almost always need to read in a loop, because the data can be split over multiple packets, and/or your receive buffer size may be too small. So usually, you would loop and buffer all the payload until you detect either an EOF or the end of a frame, and only then start trying to process the content. In particular, you should not usually try to decode text until you know you have the entire thing, because multi-byte characters may span multiple "read"/"receive" calls, so: unless you're using a stateful text decoder, you may incorrectly decode such characters.



              The behaviour you're seeing would be common to almost all platforms and languages; it isn't specific to Java/C#.






              share|improve this answer
























                6












                6








                6






                Based on the code shown, it would be entirely expected to sometimes get an empty payload, because if the payload packets haven't arrived yet: inFromDotNet.available() will be zero.



                Basically, .available() (and equivalent) should never be used to determine anything about the content, other than "there are bytes currently buffered" (perhaps to choose between sync read and async read).



                There are two approaches commonly used here:




                • use EOF to indicate the end of the payload, i.e. read until the socket says it is closed and everything has been read; how you detect this depends on the specific socket API (for example, in .NET, it would be when Receive returns a non-positive number)

                • implement some kind of basic framing protocol


                The first option is relevant if you will only ever send one message per socket; the second option is necessary if you will be sending multiple messages per socket. A basic framing protocol could be as simple as "messages are separated by newline characters", but in many cases you may need binary-safe framing, such as a length prefix. For example, your JSON could contain newlines, which could incorrectly be interpreted as the end of a frame.



                In either case: with sockets you almost always need to read in a loop, because the data can be split over multiple packets, and/or your receive buffer size may be too small. So usually, you would loop and buffer all the payload until you detect either an EOF or the end of a frame, and only then start trying to process the content. In particular, you should not usually try to decode text until you know you have the entire thing, because multi-byte characters may span multiple "read"/"receive" calls, so: unless you're using a stateful text decoder, you may incorrectly decode such characters.



                The behaviour you're seeing would be common to almost all platforms and languages; it isn't specific to Java/C#.






                share|improve this answer












                Based on the code shown, it would be entirely expected to sometimes get an empty payload, because if the payload packets haven't arrived yet: inFromDotNet.available() will be zero.



                Basically, .available() (and equivalent) should never be used to determine anything about the content, other than "there are bytes currently buffered" (perhaps to choose between sync read and async read).



                There are two approaches commonly used here:




                • use EOF to indicate the end of the payload, i.e. read until the socket says it is closed and everything has been read; how you detect this depends on the specific socket API (for example, in .NET, it would be when Receive returns a non-positive number)

                • implement some kind of basic framing protocol


                The first option is relevant if you will only ever send one message per socket; the second option is necessary if you will be sending multiple messages per socket. A basic framing protocol could be as simple as "messages are separated by newline characters", but in many cases you may need binary-safe framing, such as a length prefix. For example, your JSON could contain newlines, which could incorrectly be interpreted as the end of a frame.



                In either case: with sockets you almost always need to read in a loop, because the data can be split over multiple packets, and/or your receive buffer size may be too small. So usually, you would loop and buffer all the payload until you detect either an EOF or the end of a frame, and only then start trying to process the content. In particular, you should not usually try to decode text until you know you have the entire thing, because multi-byte characters may span multiple "read"/"receive" calls, so: unless you're using a stateful text decoder, you may incorrectly decode such characters.



                The behaviour you're seeing would be common to almost all platforms and languages; it isn't specific to Java/C#.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 12 '18 at 16:52









                Marc Gravell

                777k19221262540




                777k19221262540






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266539%2ftcp-communication-between-c-sharp-and-java-servers%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Xamarin.form Move up view when keyboard appear

                    Post-Redirect-Get with Spring WebFlux and Thymeleaf

                    Anylogic : not able to use stopDelay()