Java socket client doesn't stop reading the data - java

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();

Related

Conversion of unreadable string from TCP IP port in 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.

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.

java client-server issue on client side (no System.out)

probably a noobish Q:
So i made a very simple single-threaded server/client model. Now when i execute the program in the eclipse IDE it shows me System.out's of the server and not the ones from the client.
When i press terminate, the System.out.println lines that were supposed to be generated by Client show up.
I'm struggling with this for days now.. Hopefully someone can help me out.
Thanks in advance!
SERVER:
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args)
{
new Server();
}
public Server()
{
try
{
ServerSocket serverSocket = new ServerSocket(8000); //nieuw instantie van een ServerSocket
System.out.println("Waiting for clients..");
Socket socket = serverSocket.accept(); // lister for socket requests
while(true)
{
BufferedReader inputClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
DataOutputStream clientOutput = new DataOutputStream(socket.getOutputStream());
String clientInput = inputClient.readLine();
System.out.println("Server: clientInput= : " + clientInput);
InetAddress hostAddress = InetAddress.getByName(clientInput);
String iPaddress = hostAddress.getHostAddress();
System.out.println("Server: IP = : " + iPaddress);
clientOutput.writeBytes(iPaddress);
clientOutput.flush();
}
}
catch(IOException ex)
{
System.err.println(ex);
}
}
}
CLIENT:
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
new Client();
}
public Client()
{
try
{
Socket socket = new Socket("localhost", 8000);
DataOutputStream toServer = new DataOutputStream(socket.getOutputStream());
BufferedReader fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
toServer.writeBytes("google.com" + '\n');
String ip = fromServer.readLine();
System.out.println("Client: "+ ip);
}
catch(IOException ex)
{
System.err.println(ex);
}
}
}
When you start a client and a server program, they will have 2 separate consoles. Only one is visible at a time in the "Console" view of Eclipse. That is why you only see the server's.
You can switch between the active consoles with the "Display Selected Console" icon (it's a monitor icon) and also see the active console list.
Also you have a full-duplex connection. Both the client and the server can read/write. You use a DataOutputStream - BufferedReader representation for a one-way communication which is WRONG.
DataOutputStream writes binary data, BufferedReader reads text (character) data.
You should use one of the following pairings:
DataOutputStream - DataInputStream and use writeUTF() and readUTF() methods
OR
PrintWriter - BufferedReader and use println() and readLine() methods
clientOutput.writeBytes(iPaddress);
clientOutput.write("\n".getBytes());
clientOutput.flush();
Just add these lines (second line) in your Server class.
Reason
In your Client class you are reading a line from buffer reader but you have not send any character from server indicating end of line. So in the second line we are writing new line character indicating end of line.
When you close the server, connection get reset and available input are read. Thats why your Client prints if you close the server.
Optionally if you only want to modify your Client class you can write these lines
char [] a = new char[100];
int length = fromServer.read(a);
System.out.println("Client: "+(new String(a)).substring(0,length));
Instead of these
String ip = fromServer.readLine();
System.out.println("Client: "+ ip);
Ok so after indexing the line with an '\n' and putting the line :
Socket socket = serverSocket.accept();
inside the while loop in stead of inside try{} i got rid of all my problems.
Thanks, now i'll try to multithread this thing!

EOFException in readUTF

I am getting below EOFException while using readUTF() method, please let me know how could i overcome with this problem and also please suggest how readUTF() transfers socket information over the other networks
import java.io.*;
import java.net.*;
public class GreetingServer {
public static void main(String args[]) {
String servername =args[0];
int port = Integer.parseInt(args[1]);
try {
System.out.println("Server Name "+ servername +"Port"+port);
Socket client = new Socket(servername,port);
System.out.println("Just connected to"+ client.getRemoteSocketAddress());
OutputStream outs = client.getOutputStream();
DataOutputStream dout = new DataOutputStream(outs);
dout.writeUTF("Hello From"+client.getRemoteSocketAddress());
InputStream in = client.getInputStream();
DataInputStream din = new DataInputStream(in);
System.out.println("Server Says"+ din.readUTF());
client.close();
}
catch (EOFException f) {
f.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
You have reached the end of the stream. There is no more data to read.
Possibly your server isn't using writeUTF(), or you are out of sync with it. If the server is writing lines you should be using BufferedReader.readLine().
The docs for readUtf() state;
First, two bytes are read and used to construct an unsigned 16-bit
integer in exactly the manner of the readUnsignedShort method . This
integer value is called the UTF length and specifies the number of
additional bytes to be read. These bytes are then converted to
characters by considering them in groups. The length of each group is
computed from the value of the first byte of the group. The byte
following a group, if any, is the first byte of the next group.
This suggests to me that what your trying to read with readUtf() isn't UTF, as the EOFException occurs when the End of File (EOF) is read unexpectedly.
Check that you are reading the right types in the same order that your server is sending them etc. You should be following a decided protocol, rather than blindly reading.

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