I have a TCP socket that I am opening with Java on a Raspberry Pi and a remote piece of hardware is sending data to it. Unfortunately, the data being presented to the console is not readable to the sser.
The Java code is as follows:
import java.io.*;
import java.net.*;
class TCPServer {
public static void main(String argv[]) throws Exception {
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(11111);
while(true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
I have checked with tcpdump and the hardware itself, the data is being sent and recieved by the Raspberry Pi. My hunch is the line:
clientSentence = inFromClient.readLine();
The end requirement is to take the data being sent and dump it into an SQL table, so I need to translate the TCP packet to a human readable string, hence my stumbling block here.
If your remote hardware is sending binary data, you should read it with a plain InputStream:
InputStream input=connectionSocket.getInputStream();
... and it won't be readable to a human user.
If, instead, you know certainly that it is text, you must know then in which charset it has been encoded, and set it to the InputStreamReader as a second parameter:
new InputStreamReader(connectionSocket.getInputStream(), "UTF-16")
Possible encodings:
ASCII
UTF-8
UTF-16
ISO-8859-1
ISO-8859-2
BIG-5 (for Chinese)
Related
I am trying to combine Python and Java using a socket connection. I hava a Java server and a Python client. They are able to connect to each other, and the server is able to write to the client, but when I try to send a message from the client to the server, it throws an EOFException. What should I do to get this to work?
Server code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serversocket = new ServerSocket(6000);
Socket client = serversocket.accept();
final DataInputStream input = new DataInputStream(client.getInputStream());
final DataOutputStream output = new DataOutputStream(client.getOutputStream());
output.writeUTF("Hello Client!");
String message = (String)input.readUTF();
System.out.println(message);
serversocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client code:
import socket
socket = socket.socket()
host = "localhost"
port = 6000
socket.connect((host, port))
message = socket.recv(1024)
print(message.decode())
socket.sendall("Hello Server".encode())
socket.close()
The exception:
java.io.EOFException
at java.base/java.io.DataInputStream.readFully(DataInputStream.java:203)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:615)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:570)
at Server.main(Server.java:19)
Option #1:
Replace input.readUTF() in server with this:
while(true) {
int ch = input.read();
if (ch == -1) break;
System.out.print((char)ch);
}
Option #2:
If want to read UTF-encoded strings (vs plain ASCII) on server then recommend using BufferedReader with utf-8 charset and readLine().
ServerSocket serversocket = new ServerSocket(6000);
System.out.println("Waiting for connections");
Socket client = serversocket.accept();
final BufferedReader input = new BufferedReader(
new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8)); // changed
final OutputStream output = client.getOutputStream();
//output.writeUTF("Hello Client!"); // see note below
output.write("Hello Client!".getBytes(StandardCharsets.UTF_8)) // changed
String message = input.readLine(); // changed
System.out.println(message);
client.close();
serversocket.close();
Client output:
Hello Client!
Server output:
Hello Server
Note JavaDoc of DataOutputStream#writeUTF(...) says:
First, two bytes are written to the output stream as if by the
writeShort method giving the number of bytes to follow.
Using output.write(s.getBytes(StandardCharsets.UTF_8)) is more compatible with non-Java clients. Python utf-8 decoding doesn't support the 2-byte length prefix added by writeUTF().
Finally, if want the server to handle more than one client connection, then add a loop that encloses the code after ServerSocket is created and only close the client socket inside the loop.
I'm new to Java programming and I'm just trying to get a very basic networking program to work.
I have 2 classes, a client and a server. The idea is the client simply sends a message to the server, then the server converts the message to capitals and sends it back to the client.
I'm having no issues getting the server to send a message to the client, the problem is I can't seem to store the message the client is sending in a variable server side in order to convert it and so can't send that specific message back.
Here's my code so far:
SERVER SIDE
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket (9091);
while (true) {
System.out.println("Waiting");
//establish connection
Socket client = server.accept();
System.out.println("Connected " + client.getInetAddress());
//create IO streams
DataInputStream inFromClient = new DataInputStream(client.getInputStream());
DataOutputStream outToClient = new DataOutputStream(client.getOutputStream());
System.out.println(inFromClient.readUTF());
String word = inFromClient.readUTF();
outToClient.writeUTF(word.toUpperCase());
client.close();
}
}
}
CLIENT SIDE
public class Client {
public static void main(String[] args) throws IOException {
Socket server = new Socket("localhost", 9091);
System.out.println("Connected to " + server.getInetAddress());
//create io streams
DataInputStream inFromServer = new DataInputStream(server.getInputStream());
DataOutputStream outToServer = new DataOutputStream(server.getOutputStream());
//send to server
outToServer.writeUTF("Message");
//read from server
String data = inFromServer.readUTF();
System.out.println("Server said \n\n" + data);
server.close();
}
}
I think the problem might be with the 'String word = inFromClient.readUTF();' line? Please can someone advise? Thanks.
You're discarding the first packet received from the client:
System.out.println(inFromClient.readUTF()); // This String is discarded
String word = inFromClient.readUTF();
Why not swap these?
String word = inFromClient.readUTF(); // save the first packet received
System.out.println(word); // and also print it
I am trying to get a java server and client communicating. For streaming data to the server I have this code:
Socket ClientSocket = null;
ClientSocket = new Socket(IPAddress, portInt);
DataOutputStream outToClient = new DataOutputStream(ClientSocket.getOutputStream());
outToClient.writeBytes(command);
outToClient.flush();
And for the server I have:
ServerSocket mysocket = new ServerSocket(8081);
Socket connectionsocket = mysocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionsocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionsocket.getOutputStream());
//program hangs here, client not sending
GetRequest = inFromClient.readLine();
System.out.println("Received: " + GetRequest);
These are only short portions of the overall code, I have found that the program hangs on the server side when the readLine(); is reached. I am trying to send data with writeBytes(command); where command is a string. Any suggestions? thanks.
writebytes to readline
Stop right there. If you're using readLine() you're using BufferedReader, which is a Reader, which means you should be using a Writer to talk to it, which means you should be using a BufferedWriter, and as you're reading lines you must write lines, which means writing a line terminator (which you aren't presently doing), which means you should use BufferedWriter.newline().
Or PrintWriter.println(), but don't forget to check for errors, as it swallows exceptions.
Don't directly use readLine
Instead try this
If( inFromClient.ready()){
// read string here.
}
It might be possible that buffer is not ready and you are trying to read. So it can create problem.
I have this code and for some reason it stucks at readline() line at servers end always waiting from client but client on the other end sends the data.
Both the server and client's code is available below.
Server Code
import java.io.*;
import java.net.*;
public class TCPServer {
public static final int SERVER_PORT = 6789;
public static void main(String argv[]) throws Exception {
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(SERVER_PORT);
while (true) {
Socket connectSocket = welcomeSocket.accept();
InputStream sin = connectSocket.getInputStream();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(sin));
PrintWriter outToClient = new PrintWriter(connectSocket.getOutputStream(), true);
clientSentence = inFromClient.readLine();
capitalizedSentence = clientSentence.toUpperCase() + "\r\n";
outToClient.print(capitalizedSentence);
}
}
}
Client Code
import java.io.*;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws Exception {
String hostName = "localhost";
int port = 6789;
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket(hostName, port);
PrintWriter outToServer = null;
clientSocket.getOutputStream();
BufferedReader inFromServer = null;
inFromServer=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.print(sentence + "\r\n");
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " +modifiedSentence);
clientSocket.close();
}
}
After fixing your syntax errors around outToServer, I think the problem lies in the way you're using PrintWriter around the output stream on the client's side. From the documentation:
Unlike the PrintStream class, if automatic flushing is enabled it will
be done only when one of the println, printf, or format methods is
invoked, rather than whenever a newline character happens to be
output. These methods use the platform's own notion of line separator
rather than the newline character.
Since you're using print with a manually appended new line, the message is never flushed to the socket's output stream. I believe you can fix this by using println instead:
outToServer.println(sentence);
Even better would be to use DataInputStream and DataOutputStream instead of BufferedReader and PrintWriter, as those are better suited for sending and receiving arbitrary data over a socket stream.
This question already has an answer here:
to read the packet of bytes on client(client Socket) from server(ServerSocket) using java
(1 answer)
Closed 7 years ago.
i m creating connection oriented server/client(TCP) socket.i have created whole server socket and i have written packet on server socket successfully and i have created client socket also but i m not be able to read packet so please give me the idea about read the packet(code or example) on client socket and tell clearly that can i read a packet on client socket or not if no then what should use in place of client and server socket
You don't generally read a packet at a time - you read from the InputStream returned by Socket.getInputStream(). You should almost certainly be treating the connection as a stream, rather than even attempting to handle individual packets.
If you still run into problems, it would really help if you could post some code to show how you're connecting the socket etc.
I had to implement such a thing for my networking course in college.
Here's an excerpt from the book
TCPServer.java
import java.io.*;
import java.net.*;
class TCPServer
{
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
TCPClient.java
import java.io.*;
import java.net.*;
class TCPClient
{
public static void main(String argv[]) throws Exception
{
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
}
Hopefully this will be sufficient to figure out what you did wrong. Good luck!