BinaryWriter to MemoryStream in Java - java

I have C# program that makes a tcp connection with another c# program. In the c# program to send an message I did this :
private TcpClient client;
private void SendPulse()
{
byte[] send_Buffer;
port = 11000;
while (true)
{
lock (locked)
{
try
{
BlockID = 1003;
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter w = new BinaryWriter(ms))
{
NetworkStream stream = client.GetStream();
BlockID = 1003;
LengthMessage = 84;
// Header :
w.Write(BeginMessage);
w.Write(BlockID);
w.Write(LengthMessage);
w.Write(RadarID);
w.Write(Time);
w.Write(ModeSystem);
w.Write(Icd_primary_var);
w.Write(Icd_secondary_ver);
// Data :
w.Write(StatusSystem);
send_Buffer = ms.ToArray();
stream.Write(send_Buffer, 0, send_Buffer.Length);
Thread.Sleep(3000); // Send pulse every 3 seconds.
}
}
}
catch
{
}
}
}
}
The idea is to write in binarywriter and than convert the memory we wrote on to byte array and to send it.
Now I have Java programming. I want to do it too, I have connection with C# but I dont know how to send it. I did DataOutputStream but it send every parameter alone, I want all in 1 array of bytes exactly like in the c# code.
Thanks for helpers.

If you want to use DataOutputStream, you can wrap it around a BufferedOutputStream and flush() it when you are done.
Or you can use an NIO ByteBuffer and write it to the socket.
To make the message easier to decode I would add the length to the start, unless you know it every message will be that length.

Related

Getting Garbage value while reading from serial port in java

I am reading data from serialport using jSerialComm package. I am getting following data
A total of 22 bytes are being received and I am getting these three garbage bytes too. The readable data is correct but what these garbage characters are happening?
Following is my code.
public static void main(String[] args) {
SerialPort serialPort = SerialPort.getCommPort("/dev/ttyUSB0");
if(serialPort.openPort())
{
System.out.println("Port Opened Successfully...");
}
else
{
System.out.println("Unable to open port....");
return;
}
serialPort.setComPortParameters(1200, 8, 1, 0);
try
{
while(true)
{
while(serialPort.bytesAvailable() != 0)
{
Thread.sleep(1000);
byte[] readBuffer = new byte[serialPort.bytesAvailable()];
int numRead = serialPort.readBytes(readBuffer, readBuffer.length);
String data = new String(readBuffer);
System.out.println("Read "+numRead+ " bytes." + readBuffer);
System.out.println(data);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
serialPort.closePort();
System.out.println("done...");
}
SerialPort.readBytes seems to be not thread safe, thus yielding "garbage" when called during character reception.
I suggest to use the snippet from the author's example which worked fine for me:
// Get a new instance of SerialPort by opening a port.
SerialPort port = SerialPort.open("COM2");
// Configure the connection
port.setTimeout(100);
port.setConfig(BaudRate.B115200, Parity.NONE, StopBits.ONE, DataBits.B8);
// You have the choice, you can either use the Java NIO channels
// or classic Input/Ouput streams to read and write data.
//DEL SerialChannel channel = port.getChannel();
InputStream istream = port.getInputStream();
// Read some data using a stream
byte[] byteBuffer = new byte[4096];
// Will timeout after 100ms, returning 0 if no bytes were available.
int n = istream.read(byteBuffer);
// *** Use n bytes of byteBuffer ***
//DEL ...
port.close();
//DEL : removed from the original code for clarity
You did not explain the protocol but I suggest to look it up. Presumably these are control characters or like a comment suggests binary data. You create a String from a byte buffer without an encoding so this also depends on your environment/ JVM's default encoding.
Try treating the first and the last two bytes as specified in the protocol in use for your project. It might also be related to jSerialComm not removing serial signalling, e.g. handshake, EOT and such.
If you're reverse-engineering the protocol instead maybe also try another library like RxTx to see if the bytes stay the same.
To inspect the bytes safely use for example BigInteger to print out a Hex-String instead:
BigInteger bigInteger = new BigInteger(1, bytes);
System.out.printf("%0" + (bytes.length << 1) + "x", bigInteger);
Use this code block and it will run perfectly;
serialPort.addDataListener(new SerialPortDataListener() {
#Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
}
#Override
public void serialEvent(SerialPortEvent serialPortEvent) {
if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_RECEIVED) {
return;
}
byte[] newData = serialPortEvent.getReceivedData();
String data = new String(newData);
System.out.println(data);
}
});

Java DataOutputStream doesnt write all messages ( TCP Socket )

in my Client-Server application I found a strange error. I got the following Methods :
sendLoginResponse();
sendPlayerList();
sendCurrentLevelState();
Each Methods sends a byte array to the Client-Side
If I only call 2 of them, everything works fine and the Client-Side gets all the sent byte arrays. But if I call all 3 of them only the first and second one arrive the Client, the order of the following methods doesnt matter. but the Server says all of them were send. To write to the Client iam using the
write(byte[] b, int off, int len); method
all The lenghts within the packages make sense too.
Here comes the strange point:
if I add a Thread.sleep(1000); after the second Method, the third one does now arrive the Client after the sleep. I Have also tried to flush the DataOutputStream after every write call, but this didnt help.
EDIT:
So let's say I'd send 3 Login-Response
The Method's that gives me the byte[]:
public byte[] getLoginResponse(int playerID){
byte[] msg = new byte[4];
short shortMsgLength = 4;
byte[] msgLength = shortToBytes(shortMsgLength);
msg[0] = 2;
msg[1] = msgLength[0];
msg[2] = msgLength[1];
msg[3] = (byte) playerID;
return msg;
}
private byte[] shortToBytes(short value) {
byte[] returnByteArray = new byte[2];
returnByteArray[0] = (byte) (value & 0xff);
returnByteArray[1] = (byte) ((value >>> 8) & 0xff);
return returnByteArray;
}
And the Send Method:
private void sendLoginResponse() {
try{
byte[] msg = rfcObject.getLoginResponse(playerID);
out.write(msg,0,msg.length);
}catch(Exception e){
System.err.println(e.getMessage());
System.exit(0);
}
}
So if I call the sendLoginResponse(); three times in a row, the client only recieves 2 byte-arrays, but the server says it has been sent 3 times. If i add a
Thread.sleep(1000); `after the second Method-Call, everything works fine..`
The Client that reads the message runs in a Thread:
public void run(){
while(true){
try {
byte[] data = new byte[MAX_DATA_SIZE]; // MAX_DATA = 255
byteCount = in.read(data);
} catch (IOException ex) {
handleExceptionError(ex);
}
}
}
thank you!
if I call the sendLoginResponse(); three times in a row, the client only recieves 2 byte-arrays, but the server says it has been sent 3 times.
This is because TCP is a stream-oriented protocol. Meaning it doesn't know or care how your messages are delimited. There's no concept of individual messages in TCP, just a stream of bytes, with the guarantee that the order of bytes is preserved.
So when the sender calls three write, the three byte arrays are simply concatenated over the connection and arrives at the receiver in the same order, but the receiver doesn't necessarily need three read to get all the bytes, and even if it does take three read, the read doesn't necessarily gives you the same byte array passed to each corresponding write.
Your message already have the necessary information to get the individual message back from the byte stream:
// Client code for reading individual messages from a TCP connection
byte type = din.readByte();
// Read the message length, little-endian.
// We cannot use din.readShort because it's big-endian
int lenLo = din.read();
int lenHi = din.read();
short len = (short)(lenLo | (lenHi << 8));
byte [] body = new byte[len];
din.readFully(body);
DataOutputStream and TCP don't lose data.
As almost invariable seen in questions of this nature, the problem is at the receiving end. You are probably assuming that `read()' fills the buffer, and ignoring the count that it returns.
Based on your protocol description in comments, you should be using DataInputStream.readFully() in this circumstance:
byte type = din,readByte();
int length = din.readShort();
byte[] data = new byte[length];
din.readFully(data);

Transferring Large Data with UDP protocol

I know TCP is better to send file but I have a homework about sending file via udp protocol . Is there any code example in C# or Java about sending file?
I have server-client example to send and recieve message. I tried to send the file using the same way but could not succeed. I may need an algorithm to divide the file small parts and send them via datagram, and I have an idea to put "md5" of the part as header of the array to check if the packet is lost or not.
Here is my try , my server side in java;
// 1. creating a server socket, parameter is local port number
sock = new DatagramSocket(7777);
// buffer to receive incoming data
byte[] buffer = new byte[65536];
DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
byte []bigByteArray=new byte[1024*1024*1024*1024];
// 2. Wait for an incoming data
echo("Server socket created. Waiting for incoming data...");
ByteBuffer target = ByteBuffer.wrap(bigByteArray);
// communication loop
while(true)
{
try
{
sock.receive(incoming);
String s = new String(incoming.getData());
if(s=="finish") break;
target.put(incoming.getData());
}
catch(Exception e)
{
}
}
fos.write(bigByteArray);
fos.close();echo("RECIEVED");
and my client side;
String s;
Path path=Paths.get("C:\\Users\\Toshiba\\Desktop\\aa.txt");
byte[] data = Files.readAllBytes(path);
try
{
sock = new DatagramSocket();
InetAddress host = InetAddress.getByName("localhost");
//take input and send the packet
byte [] part;
for (int i = -1; i < data.length; i=i+100)
{
if(sock.isConnected())
{
part=Arrays.copyOfRange(data,i+1,i+100 );
}
else i=i-100;
}
byte [] f="finish".getBytes();
DatagramPacket finalpac = new DatagramPacket(f ,f.length , host , port);
sock.send(finalpac);
}
Thank you in advance.
Several issues:
The following isn't correct:
sock.receive(incoming);
String s = new String(incoming.getData());
The final line should be
String s = new String(incoming.getData(), incoming.getOffset(), incoming.getLength());
and if you aren't receiving text you shouldn't be converting the data to a String at all.
Remove the sock.isConnected() test. DatagramSockets are not usually connected, and you certainly haven't connected this one.
The loop in which this is embedded does nothing useful. You are only sending the word "finish".

Communication between C# and Java Sockets halting?

I'm using sockets to communicate between C# and Java. However, My stream in C# keeps freezing whenever I try to read from it. I'm wondering if someone might be able to help me out.
Java Code -
public void Send(String message) throws Exception {
sock = new Socket("127.0.0.1", 2913);
PrintStream PS = new PrintStream(sock.getOutputStream());
PS.println(message);
}
C# Code -
private static void Listen(){
serverSocket.Start ();
while (true) {
TcpClient Client = serverSocket.AcceptTcpClient ();
NetworkStream stream = Client.GetStream ();
byte[] read = new byte[10025];
stream.Read (read, 0, (int)Client.ReceiveBufferSize);
Client.GetStream().Flush();
string dataFromClient = System.Text.Encoding.ASCII.GetString (read);
//Output data from client
Client.Close();
}
}
I've managed to ensure that the client is connecting, and that all of the C# code is executing up to the point where it calls
stream.Read();
I'm wondering if someone might know why it is halting on stream.Read();. Is my java trying to send the message before C# has a chance to listen to it? If so, how would I fix that. I've tried using
while(!sock.isConnected()) Thread.sleep(1);
in my Java, but it didn't help.
I ended up fixing it by using this for my C# function.
private static void Listen(){
serverSocket.Start ();
while (true) {
TcpClient Client = serverSocket.AcceptTcpClient ();
StreamReader sr = new StreamReader(Client.GetStream ());
string dataFromClient = sr.ReadLine();
//Output Data From Client
Client.Close();
}
}
I guess using the stream reader instead of trying to read the bytes myself fixed it.

How to read bytes on receiver in socket stream (java)

I have set up a socket connection between a server and i client. Right now i'm trying to send data from my client to the server. Actually the data is a byte array which contain numbers in the index 14 to 27. An example of the array is here:
{27, 14, 16, 18, 20, 22, 14, 17, 15, 17} and so on.
Have made it as an byte array because the data have to be in bytes.
The difficulty is that when i sent a line from the array to the server, i don't know how to read it other than a string. And if it is a string, it return some weird numbers like the one you see in the picture.
Some code how i do it:
Sender
for (int i = 0; i < data.length; i++) {
writer.write(data[i]);
}
writer.flush();
writer.close();
Receiver
public void readResponse(Socket client) throws IOException{
String userInput;
BufferedReader stdIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("Response from client:");
while ((userInput = stdIn.readLine()) != null) {
System.out.println(userInput);
}
}
My byte array is made like this:
private byte data[] = new byte[12];
if i change it to Byte with uppercase, i can read it with my code, but i'm not sure if it in bytes then? Have to use some math to calculate an average.
private Byte data[] = new Byte[12];
So, how do i read it?
Update:
So i understand that i'm going to use a different input/output stream. Right now i have changed it too a Datainput and output stream.
Code looks like this:
Server
public void readResponse(Socket client) throws IOException{
DataInputStream input = null;
byte data;
try {
input = new DataInputStream(client.getInputStream());
}
catch (IOException e) {
System.out.println(e);
}
System.out.println("Response from client:");
while ((data = input.readByte()) != -1) {
System.out.println(data);
}
}
Client
public void sentData(Socket client) throws IOException{
DataOutputStream output = null;
try {
output = new DataOutputStream(client.getOutputStream());
}
catch (IOException e) {
System.out.println(e);
}
for (int i = 0; i < data.length; i++) {
output.write(data[i]);
}
output.flush();
output.close();
}
As you can see in my client, i want to sent a byte at a time to the server, but it still shows weird numbers like [?][?][?].
All the *Reader classes are meant for text data only. When working with binary data, just use the streams directly. In your case, just use BufferedInputStream instead of BufferedInputStreamReader.
There is also TCP protocol your program has to conform to, with it own buffering and flushing mechanism. This existence of this layer is non-obvious when you first code your Java program with raw byte stream.
I would suggest you either construct a deterministic protocol, e.g. using a marker byte like "000" to indicate the start of your transmission, and encoded payload that excludes the "000", and finally, "000" to terminate your transmission. (This still doesn't deal with loss in transmission well).
Alternatively, Google's Protocol Buffer, or Msgpack to help along with some of the intermediary process.

Categories

Resources