Socket reading strategy in java - java

I have a project where I will receive data from a TCP port, I need to be constantly waiting to check if I receive data.
My code for now is:
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip,8000));
while(true){
DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
InputStream inFromClient = socket.getInputStream();
while(true){
int i = inFromClient.read();
System.out.println("data = " + i);
l++;
}
I don't like this strategy based in while(true), There is some strategy to receive data from a callback or something similar?

You can use java File I/O (Featuring NIO.2). Please follow the link for sample
https://github.com/dublintech/async_nio2_java7_examples/blob/master/echo-nio2-server/src/main/java/com/alex/asyncexamples/server/AsyncEchoServer.java

Related

How to communicate between Java and Dart through Socket

I would like to run a combination of Dart and Java code, that can communicate with each other.
Therefore I chose to go with sockets, with the server socket written in Java and the client socket written in Dart.
This is the code I wrote:
Server
ServerSocket server = new ServerSocket(12345);
server.setSoTimeout(0);
System.out.println("waiting for connection...");
while (true) {
try {
Socket client = socket.accept();
DataInputStream input = new DataInputStream(client.getInputStream());
DataOutputStream output = new DataOutputStream(client.getOutputStream());
System.out.println("connected to " + client.getLocalSocketAddress() + ".");
while (true) {
output.write(input.readLine());
}
} catch (IOException e) {
System.out.println("disconnected.\n\nwaiting for connection...");
}
}
Client
Socket client = await Socket.connect('localhost', 12345);
client.write('hello there\n');
client.close();
Unfortunately the server does not receive the ping message sent by the client.
By now I suppose, that the problem lies in the Dart code, because when executing a client written in Java worked just fine.
Do you know, how to solve this? If so, please let me know ho. Thank you in advance!
Please note:
As there will never be more than one client at a time, I chose to go with this approach. I am aware, that normally this is no good style.
In the documentation for close() on the Socket class:
NOTE: Writes to the IOSink may be buffered, and may not be flushed by a call to close(). To flush all buffered writes, call flush() before calling close().
https://api.dart.dev/stable/2.7.1/dart-io/Socket/close.html
I do not know why, but it seems that the problem lies in the DataInputStream/DataOutputStream.
Here is what worked:
Server
ServerSocket server = new ServerSocket(12345);
server.setSoTimeout(0);
System.out.println("waiting for connection...");
while (true) {
try {
Socket client = socket.accept();
BufferedWriter output = BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("connected to " + client.getLocalSocketAddress() + ".");
while (true) {
output.writeUTF(input.readUTF());
}
} catch (IOException e) {
System.out.println("disconnected.\n\nwaiting for connection...");
}
}
Client
Socket client = await Socket.connect('localhost', 12345);
client.write('hello there\n');
client.close();
This is working for me.
Socket client = socket.accept();
byte[] b = new byte[100];
client.getInputStream().read(b);
System.out.println(new String(b));

DataOutputStream.write() not visibly working, but DataOutputStream.writeUTF() is

I have a client/server pair in which I have this messaging application to which i'm trying to add SSL support. The client/server normally use DataInputStream and DataOutputStream to send/receive their info, working with byte arrays (DataOutputStream.write(byte[]) and DataInputStream.readFully(byte[])). But for some reason, that doesn't work with SSL sockets. I've tried using DataOutputStream.writeUTF() and DataInputStream.readUTF() and it works. I even tried using other types of reader/writers like BufferedReader/BufferedWriter, and they work, but when I try to use bytes, it doesn't send anything. What's weirder is the fact that after checking the DataOutputStream.size() in both sides, they both print that they have sended data.
Server side:
logger.info("Waiting to accept a new client socket");
clientSocket = (SSLSocket) serverSocket.accept();
logger.info("Socket accepted successfully");
DataOutputStream dataOutputStream=newDataOutputStream(clientSocket.getOutputStream());
DataInputStream dataInputStream=new DataInputStream(clientSocket.getInputStream());
logger.trace("Socket is going to read");
int data=dataInputStream.available();
byte[] message=new byte[data];
dataInputStream.readFully(message);
logger.trace("Message received: {}",message);
logger.trace("Gonna respond");
if(message.length>0){
dataOutputStream.write(message,0,message.length);
}else{
String response=new String("wot?".getBytes(),"ASCII");
dataOutputStream.write(response.getBytes(),0,response.getBytes().length);
}
dataOutputStream.flush();
logger.trace("Chars written: {}",dataOutputStream.size());
Client side:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
logger.trace("SSL Socket factory created");
javax.net.ssl.SSLSocket sslSocket = (javax.net.ssl.SSLSocket)sslsocketfactory.createSocket(url, port);
logger.trace("SSL Socket created");
sslSocket.setSoTimeout(6000);
outputStream = sslSocket.getOutputStream();
inputStream=sslSocket.getInputStream();
DataOutputStream dataOutputStream=new DataOutputStream(outputStream);
DataInputStream dataInputStream=new DataInputStream(inputStream);
logger.trace("Input and output created");
//dataOutputStream.writeBytes(frame);
//dataOutputStream.writeUTF(frame);
dataOutputStream.write(frame.getBytes(),0,frame.getBytes().length);
dataOutputStream.flush();
logger.trace("Frame {} sent",frame);
logger.trace("Bytes sent: {}",dataOutputStream.size());
int data=dataInputStream.available();
byte[] messageRead = new byte[data];
dataInputStream.readFully(messageRead);
Any help would be highly appreciated. I've been looking around and I don't know what else to try.

how to send TCP Requests in java

I am using Sockets to connect using TCP and I want to make different calls. e.g. Get InputValue
I have these type of different requests which I want to make from already running server.
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
String func="Get inputvalue";
byte[] tRequest = encoder.string2bytes(func);
out.write(tRequest);
out.flush();
System.out.println("write done");
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
It says it connected as just connected printout got printed. Write done print is also printed but no data is returned and the program keeps on running.
If I use telnet then this same request call returns data successfully.
So the question is how to make TCP calls in java?
Update: I solved this by:
PrintWriter toServer =
new PrintWriter(client.getOutputStream(),true);
BufferedReader fromServer =
new BufferedReader(
new InputStreamReader(client.getInputStream()));
toServer.println("Get inputvalue\r\n");
String line = "";
System.out.println("Client received: ");
while ((line = fromServer.readLine()) != null) {
System.out.println(line);
}
but the program keeps on running in the while loop and prints nothing. how to check that response is ended?

Java socket programming writebytes to readline

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.

Broken pipe using DataInputStream and DataOutputStream and sockets

I set up a client and server sockets. When I use classes ObjectOutputStream and ObjectInputStream and the method readObject/writeObject everything works fine.
It simulates communication with a robot that I know for sure interprets correctly only method
DataOutputStream.writeBytes.
So I set up the new architecture for simulation since the robot is not available for testing on a daily basis.
In the following code where ObjectOutputStream/ObjectInputStream readObject/writeObject were replaced with DataInputStream/DataOutputStream writeBytes and IOutils.toByteArray.
The server socket correctly receives the message but when it tries to write back a response I get a broken pipe as if the connection was closed somewhere.
Notice that I never close sockets or streams because the robot can answer even after 30 seconds.
Any help to make DataOutputStream.writeBytes work would be appreciated.
Here's the non-working code:
Client:
Socket serverSocket = new Socket("server", 9899);
DataOutputStream outputStream = new DataOutputStream(serverSocket.getOutputStream());
//ObjectOutputStream outputStream = new ObjectOutputStream(serverSocket.getOutputStream());
//outputStream.writeObject("\n" + "message" + "\r");
outputStream.writeBytes("\n" + "message" + "\r");
outputStream.flush();
DataInputStream inputStream = new DataInputStream(serverSocket.getInputStream());
//ObjectInputStream inputStream = new ObjectInputStream(serverSocket.getInputStream());
byte [] bytes = IOUtils.toByteArray(inputStream);
String serverResponse = new String(bytes,"UTF-8");
// String serverResponse = (String)inputStream.readObject();
Server:
ServerSocket serverSocket = new ServerSocket(9899);
while (true) {
Socket socket = serverSocket.accept();
//ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
byte [] bytes = IOUtils.toByteArray(inputStream);
String message = new String(bytes,"UTF-8");
//String message = (String) inputStream.readObject();
Thread.sleep(15000);
//ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
//outputStream.writeObject("server response");
outputStream.writeBytes("server response"); //EXCEPTION THROWN HERE FOR BROKEN PIPE
outputStream.flush();
}
Thanks for your time
IOUtils.toString(InputStream) must read the stream until its end, which would imply that the peer has disconnected. So you can't write to it.
If you're exchanging Strings with data streams you should use writeUTF() and readUTF().
Or read and write lines, with a BufferedReader/Writer.

Categories