C# TcpClient to netty not always arriving - java

Me and a friend are working on a project which requires us to communicate between a C#.NET application and a Java application.
We're using the TcpClient and BinaryWriter classes on the .NET side of things to send and receive things. We're using code similar to this to send things:
byte[] content = //we're getting our content here
Writer.Write(new byte[9]); //this is the BinaryWriter with the NetworkStream of the TcpClient
Writer.Flush();
On the Java side of things, we're using netty to handle our networking. To receive the content we send from the .NET side, we add a ChannelInboundHandlerAdapter to the pipeline and use the channelRead method to read the content:
public void channelRead(ChannelHandlerContext ctx, Object received)
{
ByteBuf receivedByteBuf = (ByteBuf)received;
this.bytesRead = receivedByteBuf.readableBytes();
System.out.println("Received " + this.bytesRead + " bytes.");
final byte[] buffer = new byte[this.bytesRead];
receivedByteBuf.markReaderIndex();
receivedByteBuf.readBytes(buffer);
receivedByteBuf.resetReaderIndex();
}
Now the strange thing is, that when we try sending content, it doesn't always arrive in one piece. Sometimes we only receive all but some bytes we originally sent, which arrive in a new call of channelRead. In this example, only 6-8 bytes would arrive. This is very strange, as this only happens when using .NET. We tried sending content using python and everything worked fine and it arrived in one channelRead call.
import socket
import string, random
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 8888))
s.send(''.join(random.choice(string.lowercase) for x in range(500)))
s.close()
Unfortunately, the nature of our project prevents us from changing our Java networking library, so we're stuck with netty.
Did we miss some setting in netty or does this have to do with the nature of the .NET TCP libraries? We would appreciate any help we can get.

Related

Java Socket Packet Interception

I'm trying to write a socket program in Java that intercepts data/packets.
I've successfully written this in python:
import socket
def createListener(port):
srvSock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
srvSock.bind(('localhost', port))
srvSock.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
while True:
raw_data, addr = srvSock.recvfrom(65536)
print('data: ' , raw_data)
createListener(80)
This is my basic Java socket program
public static void main(String[] args) {
try{
ServerSocket ss = new ServerSocket(80);
Socket s = ss.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
String str = (String)dis.readUTF();
System.out.println("data: "+str);
ss.close();
} catch(IOException i){
System.out.println(i);
}
}
However, when run, it doesn't intercept all data moving through the port on the network like the python program does. Specifically this line srvSock.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) in the Python script enables the socket to listen to the port and capture/intercept the entirety of the data going through it.
I cannot find a Java alternative to this syntax or any solution to my problem at all for that matter.
I would appreciate any help in how to use sockets to intercept packets on a network port.
Thanks
Im fairly certain what you are trying to do cannot be done with Java. It looks like you are trying to use "promiscuous mode", but Java sockets cannot be started in promiscuous mode. Java sockets are an end-to-end implementation: they can't listen on the network port for all traffic. For sure the network port would have to be in promiscuous mode, but I don't think Java is the right choice for you.
The only thing I can think of that might get you there would be doing a native call in something like JNI, but I wouldn't even really know where to start with that.
Here is a really old post that I found that is kind of related: java socket and web programing
From the looks of it, you're trying to read incoming bytearrays as string lines.
If that is so, this is what I do to read lines without missing a single line (In Kotlin):
socket.getInputStream().bufferedReader(Charsets.UTF_8).forEachLine {
it -> { /* Do what you wanna do with the input */ }
}
In Java, it's much less abstract :
BufferedReader(InputStreamReader(socket.getInputStream(), Charsets.UTF_8), 8 * 1024)
Then, use lines from this buffered reader as a line sequence to read your incoming lines.

Java tcp socket does not receive properly

Hi let me get straight to the problem. I have a big JSON packet that the server sends to this client once the client is authenticated
But the packet comes back in a weird way like it's split or something example:
The JSON should be:
Received: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,"ItemSlots":30}
When it comes through:
Received: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,
Received: "ItemSlots":30}
Why does it split the packet or something when it comes to the client and how can I fix this anyway?
Java Receive Code:
private class ClientThread extends Thread {
public void run() {
try {
while (selector.select() > 0) {
for (SelectionKey sk : selector.selectedKeys()) {
selector.selectedKeys().remove(sk);
if (sk.isReadable()) {
SocketChannel sc = (SocketChannel)sk.channel();
ByteBuffer buff = ByteBuffer.allocate(1024);
String content = "";
while (sc.read(buff) > 0) {
sc.read(buff);
buff.flip();
content += charset.decode(buff);
buff.clear();
}
System.out.println("Recieved: " + content);
sk.interestOps(SelectionKey.OP_READ);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks have a wonderful day.
Hi lemme get straight to the problem so i got a big JSON packet that the server sends to this client once the client is authenticated
You mean you have a big JSON message. Packets are things that network protocols used to exchange information.
But the packet comes back in a weird way like its split or something example:
Unless you're looking at the wire, you aren't looking at packets. You're looking at the bytes you got from your end of the TCP connection.
The JSON should be:
Recieved: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,"ItemSlots":30}
When it comes through:
Recieved: {"UserID":1,"PlayerID":2,"EXP":0,"Lvl":1,"Coins":0,
Recieved: "ItemSlots":30}
Excellent. You got the same bytes. Now make a JSON parser that figures out where the message ends and parses it.
Why does it split the packet or something when it comes to the client
It splits the message into packets because that's how TCP gets the message to the other side. TCP is not a message protocol and it doesn't know or care what the application considers to be a message -- that's the application's job.
and how i can i fix this anyway?
Write a JSON parser to figure out where the messages end. You haven't implemented any code to receive JSON over TCP yet, so that won't work until you do.
TL;DR: If you want an application-level message protocol, you need to implement one. TCP is not one.
TCP protocol does not maintain message boundaries. It is not guaranteed that what the server sends is received as-is by the client and vice-versa.
If the server sends 1000 bytes data, the client application can receive the same across multiple recv or single recv. TCP does not guarantee any behaviour. "Split" can happen, it is upto the application to handle the data coming in multiple chunks, coalesce it to one unit of application data for further processing. One can see this particularly with large data sizes.
It looks like you've got a non-blocking socket channel, meaning that the while (sc.read(buff) > 0) { loop is terminating due to sc.read(buff) returning 0 since only a portion of the data sent has, at this point, been received.
Why does it split the packet or something when it comes to the client
Most likely the data is being split into two or more packets.
and how i can i fix this anyway?
Keep filling your buffer until the socket is closed by the server (read should return -1 rather than 0 in that case). You need to maintain a separate buffer per channel. If the server doesn't close its end after sending the data, you'll need to delineate in some other way; you could prefix the JSON blob with a size header, for instance.

is it necessary for the socket to immediately receive data/java

I am working on a network simulation in java. I send data from the server side to the client side. The client receives this data and then client starts to read data which has come into its own buffer and shows it on the client terminal that how much data has arrived further "whereas" on the server side, it keep sending data. Receiving statements are also written on the client side but the client is busy in reading in its buffer. After it finishes, it receives data from server. Sometimes, when I run the program, the data sent from the server is not read and exception occurs "Connection reset". Is it timing issue? Should the data sent from server be immediately received at client side? or due to some other reason?
Here is the server's side code:
soc.sendHP_Grant(grantSizeHP2); //soc is the socket's object
soc.sendLP_Grant(grantSizeLP2);
soc.sendGrant_info(grantStartTime);
soc.sendGrant_info(grantEndTime);
whereas on the client side:
receivedGrant_HP = socOnu.receiveReportHP();
receivedGrant_LP = socOnu.receiveReportLP();
startTime = socOnu.receiveGrant_Info();
endTime = socOnu.receiveGrant_Info();
onu2.accessTraffic("ONU2-Traffic-report-2.txt");
After that, I am again using the server's side code to send further data and then again I use client's side code to receive data. According to me, it's happening because I am not immediately receiving data at client side. Please mention the solution or if there is some other reason. Please mention with solution. Thanks in advance
This is the code which (is causing problem) I am using for receiving data at client side:
public double receiveReportHP() throws IOException{
DataInputStream dis = new DataInputStream(socket.getInputStream());
double reportHP = dis.readDouble(); //exception on this line
return reportHP;
}
whereas the sending side code is (working fine):
public double receiveReportForHP() throws IOException{
DataInputStream dis = new DataInputStream(socket.getInputStream());
double reportHP = dis.readDouble();
return reportHP;
}

Android programming: Change TCP to RTP

I am working on an Android app including client and server that client app sends camera captured data to server for processing, and server sent the result back to client to display. The current version of it uses TCP for transmitting data, so the code includes something like:
Client side:
send(){
Socket socket = new Socket();
DataOutputStream outputStream = new DataoutputStream(socket.getOutPutStream());
outputStream.writeUTF(...)
...
outputStream.write(data);
outputSteram.flush();
...
}
receive(){
DataInputStream dataInputStream = new DataInputStream(...);
...
dataInputStream.readFully(data, 0, length);
...
}
Server side:
...
serverDataInputStream.readFully(data,0,length);
//process data
...
serverDataOutputStream.write(reply)
...
I tried to change this to use UDP, but the data sent from client to server is much larger than the maximum size of a UDP packet, so have to fragment the data in client and reassemble it on server manually. It turns out to be too much troublesome.
I know RTP takes care of data fragmentation, so now I want to change this into RTP. After Googleing for a while, I found the following information:
http://sourceforge.net/projects/jlibrtp/
http://code.google.com/p/sipdroid/source/browse/trunk/src/org/sipdroid/sipua/ui/VideoCamera.java
And these two posts are very similar to what I am doing:
Android Camera RTSP/RTP Stream?
Creating RTP Packets from Android Camera to Send
But the posts just include limited sample code. Can anyone post more details and sample code here? I don't have much experience of Java and Android programming. So detailed examples or step by step instruction will be extremely appreciated!
Thank you!

Writing a WebSocket Server

I'm trying to write a WebSocket Server in both, java and C++ but I'm stuck right now.
Using java and java.net.ServerSocket/java.net.Socket I managed to get a connection and succesfully do the handshake but the data sent by the WebSocket to the Java Server is not quite what I expected.
When sending messages from javascript like this:
var count = 0;
function loop(){
websocket.send("loop: " + count + "\n");
count++;
setTimeout(loop, 100);
}
The Java server receives this, with line feeds every now and then but not for every websocket.send() that has been invoked.
?‡½÷"˜Ñ˜Mè‡×?‡AÎ3-¡C{îN?‡ŒÍ[Uà¢4%¶íi?‡$ÍåøH¢ŠˆíÖ?‡·†ÞžÛé±î?¦ê?‡'½Ø…KÒ·õ?í?‡dÒÛ‘½´á^òí?‡+ù?YG–â)Ùº?‡›?
Ë÷àb»¡¯5?‡mÉŒQ¦ã!Wéµ?ˆ:J FV%f6
The Java server retrieves values from the socket using BufferedReader.readLine()
BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line =socketReader.readLine();
This works fine for the handshake and all handshake data is readable but it does not work after the handshake is done.
Is the data after the handshake somehow encrypted? How can I read it?
EDIT :
The program files:
SocketConnectTest.html
ServerTest.java
ClientSessionTest.java
ResponseGenerator.java
output
Just run ServerTest.java and then open SocketConnectTest.html.
ClientSessionTest.initClientListener() handles the messages from the client.
SOLUTION :
For the solution see pimvdbs post below and his answer at How to (de)construct data frames in WebSockets hybi 08+?
The data coming across web sockets is raw, not string encoded data.
I'd suggest not wrapping a BufferedReader around the incoming data as packets are framed with 0x00 bytes. The crazy characters you are seeing are a result of Java not understanding the encoding that the data is in.
You will need to be responsible for splitting up the data into character and control parts. Once you've split the data up into the appropriate areas, then you can decode the data as a string.

Categories