TCP communication between C# and Java servers
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
add a comment |
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
add a comment |
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
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
java c# json tcp
edited Nov 12 '18 at 16:49
asked Nov 12 '18 at 16:42
Giedrius Electrum
107210
107210
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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#.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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#.
add a comment |
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#.
add a comment |
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#.
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#.
answered Nov 12 '18 at 16:52
Marc Gravell♦
777k19221262540
777k19221262540
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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