Conversion of unreadable string from TCP IP port in java - java

I am trying to read continuous data from TCP IP port of system using Java Socket Programming ServerSocket but I am getting unreadable string data like in following following image :
I am using following code for read data from TCP IP port :
ServerSocket server_socket;
BufferedReader input;
try {
server_socket = new ServerSocket(6666);
LOGGER.info("Server waiting for client on port "
+ server_socket.getLocalPort());
System.out.println("Server waiting for client on port "
+ server_socket.getLocalPort());
while (true) {
Socket socket = server_socket.accept();
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
try {
while (true) {
String message = input.readLine();
if (message == null) {
break;
}
}
} catch (Exception e) {
socket.close();
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
So please let me know what kind of data are in above image and what conversion I should do?
Thanks in advance.

One flaw:
The InputStreamReader is responsible for converting binary data (an InputStream) to a Reader ((Unicode) text). For that you can & should specify a text encoding, a Charset. You are using the default, platform encoding.
input = new BufferedReader(
new InputStreamReader(socket.getInputStream(), StandardCharsets.ISO_8859_1));
You can now access this server application yourself by telnet or an other terminal tool. Or even the browser by http://localhost:6666/ (telnet://localhost:6666/?).
What you are seeing does look like non-text binary data - should the default encoding not be Chinese or such.
Furthermore the code would be improved by a new thread from a thread pool handling the socket from the accept.
One should pay attention to the header lines one sends (you do not output) and then receive.

Related

Java socket client doesn't stop reading the data

Hello i'm trying to execute a socket client in Java, but the client still reading the data and don't proceed with the program execution. Any ideas?
Here's the code:
import java.io.*;
import java.net.Socket;
public class SocketTeste {
public static void main(String[] args) {
try {
Socket client = new Socket("127.0.0.1", 1987);
System.out.println("Got connection");
DataInputStream handshake = new DataInputStream(client.getInputStream());
String handshakePure = handshake.readUTF();
System.out.println("Got the handshake");
System.out.println(handshakePure);
DataOutputStream saida = new DataOutputStream(client.getOutputStream());
saida.writeUTF("Got it!");
saida.flush();
saida.close();
String returnedData = handshake.readUTF();
System.out.println(returnedData);
handshake.close();
client.close();
} catch (Exception e) {
System.out.println("ERROR: " + e);
}
}
}
I don't think if that matter, but the socket server is a PHP socket server.
DataInputStream.readUTF expects a uniquely weird message format. The first two bytes it reads are interpreted as the length of the string to read, in a big endian binary format. This is then followed by a weird non-standard text encoding similar to but incompatible with UTF-8. Most likely you should not be using DataInputStream.readUTF to read data in a program, unless you used its counterpart DataOutputStream.writeUTF to write it in the first place.
Based on your comments it sounds like your communication protocol is based on lines of text. To read lines of text, you can use for example the BufferedReader class.
BufferedReader handshake = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8));
String handshakePure = handshake.readLine();

How to process and decode incoming bytes from a TCP server

I am currently working on a Java console application. It is run through the command prompt, connects to a server application coded in python and communicates with that server over TCP. My application sends "ISND" string to server which it accepts and in return server sends three images. The format in which Images are sent in is
Where "<"">" are not actually included. "ISND" is encoded into bytes using ascii. Size is the size of the image converted into bytes from int and it is always composed of 3 bytes regardless of the size of the image. For each individual image, a message in this format is sent.
I have been using BufferedReader to read server responses but at this point, I am at a loss on how to actually handle this message. I searched for ways to separate the incoming message into components since I know the length of the first two parts which are always fixed yet I couldn't find a way to actually accomplish that goal.
It has come to the point it feels like I am smashing my head into a wall. As such, I need advice from anyone that is more familiar with Java and Socket programming on how to handle this issue.
My current code
public class ImageLabeler {
/**
* #param args
*/
public static void main(String[] args) {
String IP = args[0];
System.out.println(IP + "\n");
String port = args[1];
System.out.println(port + "\n");
Socket clientSocket;
DataOutputStream outToServer = null;
BufferedReader inFromServer = null;
String serverResponse;
try {
clientSocket = new Socket(IP, Integer.parseInt(port));
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Connection success\n");
} catch (IOException ex) {
System.out.println("Connection failed\n");
System.exit(0);
}
PrintWriter writer = new PrintWriter(outToServer, true);
try {
//outToServer.writeBytes("USER bilkentstu\\n");
//outToServer.flush();
//System.out.println("check\n");
writer.println("USER bilkentstu");
serverResponse = inFromServer.readLine();
System.out.println(serverResponse + "\n");
writer.println("PASS cs421f2019");
//outToServer.writeBytes("PASS cs421f2019\\r\\n");
//outToServer.flush();
serverResponse = inFromServer.readLine();
System.out.println(serverResponse + "\n");
writer.println("IGET");
//This is where I need to handle the incoming Image messages.
writer.println("EXIT");
} catch (IOException ex) {
Logger.getLogger(ImageLabeler.class.getName()).log(Level.SEVERE, null, ex);
}
System.exit(0);
}
}
Don't use buffered reader. You need to write the code reading a string from the InputStream of the socket one byte at a time.

Read multiple lines using BufferedReader (Socket)

I already read some threads here on stackoverflow, also some tutorials, but I don't find a solution to my problem.
I have Java client which connects to a server, then sends exactly one line to the server, and I get 2 or 3 lines as a response.
Here is my code:
public static void main(String[] args) {
String message;
String response;
try {
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket(hostname, port);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
message = inFromUser.readLine();
outToServer.writeBytes(message + '\n');
// here my program "freezes"
while ((response = inFromServer.readLine()) != null) {
System.out.println("response: " + response);
}
clientSocket.close();
} catch (UnknownHostException e) {
System.out.println("Unknown Host");
} catch (IOException e) {
System.out.println("IO Exception");
}
}
My problem is, I can read every line of the response, but my program won't exit. The line clientSocket.close(); gets never called. What am I doing wrong?
Presumably your server isn't closing the connection - therefore the underlying stream for the reader isn't closed... at any point the server could send more information. readLine() only returns null when the stream has been closed, i.e. there will definitely not be any more data.
Now we don't know anything about the protocol here, but if the expected behaviour is that the client won't send any more information, and the server will close the connection, then the bug is in the server. If the protocol states that the server will keep the connection open, then the bug is in your client code and you need to work out how to detect the end of data (or send some sort of ack that will cause the server to close the connection, or whatever).

Issue with DSCP marking using setTrafficClass and WireShark

I am trying to mark DSCP values using setTrafficClass. I have server and client set up on two different machines and I am able to print value of DSCP but I can not see it in WireShark.
I have gone through some posts online but nothing helped. I am using Windows 7 professional.
Any help would be appreciated. Thank you!
I am more testing to see how this can be done.
Here is the client code:
try {
Socket socket = new Socket(addr, 2345);
socket.setTrafficClass(10);
PrintWriter out = new PrintWriter( socket.getOutputStream(), true);
out.println("Current DSCP value: " + socket.getTrafficClass());
out.close();
socket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
Server:
try {
ServerSocket serverSocket = new ServerSocket(1234);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String fromClient = in.readLine();
System.out.println(fromClient);
in.close();
clientSocket.close();
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
In console on server side:
Current DSCP value: 10
My server code and client are on separate machines.
In wireshark I see:
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
I expect to see changes in wireshark and I only see default value zero.
Last time I worked with DSCP values in Java one had to set the java.net.preferIPv4Stack system property to true due to a bug in the JVM. Othwerwise DSCP values would not be set on the underlying socket despite appearing to work in the java.net.Socket API.
Also you may have to call setTrafficClass before connecting the socket, it may not work after connection on some platforms.
java -Djava.net.preferIPv4Stack=true ...

Communication between Client and Server using Sockets

Okay this is a revised question from earlier today, I have included code to help explain the problem. I am sending two messages from the client to the server. The server then picks the messages up and processes them. The server finally attempts to send a message back to the client(please note in the server code "testmessage"), it is here I am having problems. Either I am not recieving the message at the client side or sending it incorrectly from the server side.
public class ClientConnection {
String address, language, message;
int portNumber;
Socket clientSocket = null;
public ClientConnection(String lan, String mes, String add, int pn) throws IOException{
address = add;
portNumber = pn;
language = lan;
message = mes;
}
public String createAndSend() throws IOException{
// Create and connect the socket
Socket clientSocket = null;
clientSocket = new Socket(address, portNumber);
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Send first message - Message is being correctly received
pw.write(language+"\n");
pw.flush();
// Send off the data
// Send the second message - Message is being correctly received
pw.write(message);
pw.flush();
pw.close();
// Send off the data
// NOTE: Either I am not receiving the message correctly or I am not sending it from the server properly.
String translatedMessage = br.readLine();
br.close();
//Log.d("application_name",translatedMessage); Trying to check the contents begin returned from the server.
return translatedMessage;
}
Server Code:
public class ServerConnection {
public static void main(String[] args) throws Exception {
// Delete - Using while loop to keep connection open permanently.
boolean status = false;
while( !status){
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
// Delete - Working as of here, connection is established and program runs awaiting connection on 4444
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String language = br.readLine();
String message = br.readLine();
// Test - Works
System.out.println(language);
// Test - Works
System.out.println(message);
// Delete - Working as of here, both messages are passed and applied. Messages are received as sent from client.
TranslateMessage tm = new TranslateMessage();
String translatedMessage = tm.translateMessage(language, message);
// NOTE: This seems to be where I am going wrong, either I am not sending the message correctly or I am not receiving it correctly..
// PrintWriter writer = new PrintWriter(new BufferedOutputStream(clientSocket.getOutputStream()));
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
// Send translation back
System.out.println(translatedMessage);
// pw.write(translatedMessage+"\n");
pw.write("Return test"); // Test message!
pw.flush();
// Send off the data
pw.close();
br.close();
clientSocket.close();
serverSocket.close();
}
}
}
The code is a bit of a mess and I can see a few duplicates, I have commented where I feel the problems occour.
Thanks for any help!
You are using BufferedReader.readLine() to read the response from the server, but in the test case you are sending a string that is not terminated with a \n or \r\n, so it will not get the line as far as I can tell from the docs...
public String readLine()
throws IOException
Read a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
An additional suggestion...
When writing request response protocols like this I would not rely on line endings to terminate the requests or responses. Typically I would use either a fully formatted JSON string, or my preference is for a binary protocol where all requests and response are prepended with a binary count (usually 4 bytes bigendian/network byte order). Then the client and server reads the 4 bytes then reads the number of bytes that follow. This handles the packet fragmentation that typically happens over network connections, also it helps avoid DOS attacks by malicious users sending long strings that never terminate.
In Java you can use ByteBuffer.order() to handle bigendian numbers.

Categories

Resources