BufferedReader `is.ready()` method not working properyly - java

try {
Scanner inConsole = new Scanner(System.in);
String CONNECT_TO_WHOM = "";
Socket clientEndPoint = new Socket("localhost", 9000);
PrintWriter out = new PrintWriter(clientEndPoint.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientEndPoint.getInputStream()));
MessageFromServerThread messageFromServer = new MessageFromServerThread(in);
messageFromServer.start();
// Giving Client Details To whom To Connect
if(!in.ready())
CONNECT_TO_WHOM = inConsole.nextLine();
//System.out.println("You are Connecting To This " + CONNECT_TO_WHOM);
out.println(CONNECT_TO_WHOM);
//break;
System.out.println("To quit press q");
//inConsole.nextLine();
while(!clientMessage.equals("q")) {
out.println(clientMessage = inConsole.nextLine());
//System.out.println(in.readLine());
}
System.out.println("Check in chatClient");
} catch(Exception e) {
e.printStackTrace();
}
The code working flow:
Whenever client gets connected it the server, server will inform the client about all the other available clients, Then the from the client, server expects to which client to connect.
Here, there is a possibility that the client can be connected to another client before he wants to communicate with others. In that case the server informs that you are connected to Client X. I want to check this incident occurrence, via the if(!in.ready()).
I do understand that the in buffer could very well be empty. any way to effectively do this checking.

The java.io.BufferedReader.ready() method informs whether the stream
is ready to be read. A buffered character stream is only ready when
the buffer is not empty or if the underlying stream is ready.
So your buffer should be empty to make it return false condition

Related

Unresponsive socket read buffer

I am trying to send data to one of my servers and receive an ACK back from it. However, the processing gets hung up when waiting for a response from the server. I know for a fact that there is a connection because I can see the data reaching the server. I also know that the server is outputting data correctly because my C# client is receiving data back from the server. I will note that this client is running on a centOS virtual machine. The server is a remote windows machine. I wouldn't imagine that there would be an issue due to the virtual environment because I am able to use an SNMP java client (SNMP4j package) to make calls to a remote server. I believe my server is outputting raw binary too, but I would expect to see some kind of output either way.
// A Java program for a Client
import java.net.*;
import java.io.*;
public class Client
{
// initialize socket and input output streams
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream out = null;
private DataInputStream serveroutput= null;
// constructor to put ip address and port
public Client(String address, int port)
{
// establish a connection
try
{
socket = new Socket(address, port);
System.out.println("Connected");
// takes input from terminal
input = new DataInputStream(System.in);
// sends output to the socket
out = new DataOutputStream(socket.getOutputStream());
serveroutput = new DataInputStream(socket.getInputStream());
}
catch(UnknownHostException u)
{
System.out.println(u);
}
catch(IOException i)
{
System.out.println(i);
}
// string to read message from input
String line = "";
// keep reading until "Over" is input
while (!line.equals("Over"))
{
try
{
line = input.readLine();
out.writeUTF(line);
System.out.println(serveroutput.readLine())
}
catch(IOException i)
{
System.out.println(i);
}
}
// close the connection
try
{
input.close();
out.close();
socket.close();
}
catch(IOException i)
{
System.out.println(i);
}
}
Could be great if you would share the otherside codes. (sorry cannot comment yet)
Try use something else over writeUTF(), simply maybe a PrintStream, as mentioned by #marquis-of-lorne (read|write)UTF may be confusing by the peer.
Also this might be a good practice to flush() out the output from both side when there is nothing else to send to make sure data is sent completely.
You may also try BufferedReader over InputDataStream as you are trying to read lines. readLine() from InputDataStream is deprecated.

ESP8266 - client socket is getting closed after calling method readBytes

I'm trying to send a message from my pc to the board, but the problem is I keep losing connection before I decide to send a message.
This is code from which I'm sending the message. I create a socket, connect to the board, and then wait for inputs from the Scanner object. When I get some input I send a message to the board.
CLIENT
Socket socket = new Socket();
socket.connect(new InetSocketAddress("192.168.4.1",3000));
Scanner in = new Scanner(System.in);
String message = DataProtocol.sendMessageFormat("KLASA","METHOD","FILIP CACIC");
String message1 = DataProtocol.sendMessageFormat("KLASA","METHOD","FILIP CACIC");
message = message1 + message;
OutputStream outputStream = socket.getOutputStream();
String line;
while(!(line = in.nextLine()).equals("EXIT")){
outputStream.write(message.getBytes());
outputStream.flush();
}
This is code that is recv.message.
SERVER
void CommunicationProcessor::readFromStream(WiFiClient* wifiClient){
CLIENT_ACTIVE = true;
while(CLIENT_ACTIVE){
Serial.println(wifiClient->connected()); -> returns 1
int bytesRead = wifiClient->readBytes(buffer,1024); -> returns 0
Serial.println(wifiClient->connected()); -> returns 0
dataManager.appendData(bufferReader.getDataReaded(buffer,bytesRead));
if (checkIfEndLine(bytesRead)){
handleDataRecv();
dataManager.clearBuffer();
}
}
Serial.println("CLIENT QUIT");
}
Before method readBytes, I call method connected() and it returns 1. So everything is fine.
Method readBytes returns 0, because I did not yet send any message.
After that, I call connected() one more time and this time it returns 0.
Now if I remove this Scanner object and loop from code and send a message immediately, a server will recv. message.
Socket socket = new Socket();
socket.connect(new InetSocketAddress("192.168.4.1",3000));
Scanner in = new Scanner(System.in);
String message = DataProtocol.sendMessageFormat("KLASA","METHOD","FILIP CACIC");
String message1 = DataProtocol.sendMessageFormat("KLASA","METHOD","FILIP CACIC");
message = message1 + message;
OutputStream outputStream = socket.getOutputStream();
outputStream.write(message.getBytes());
outputStream.close();
My questions are why is connection closed after I call method readBytes?
EDIT
I just tested with this code and connection still get lost.
Line "Client alive" only gets printed one time.
SERVER
void loop(){
delay(1000);
if (client){
Serial.println("Client alive");
Serial.println(client.connected());
}else{
client = server.available();
if (client){
Serial.println(client.connected());
}
}
}
EDIT 2
I found the problem. I was using board as WIFI-ACCESS POINT, but when I connected board to my router and my pc, everything works fine.
So now my questions is why am I losing connection when board is configured as ACCESS-POINT?
EDIT 3
I found what was causing the problem. I had problem with connecting to wifi access point so i called method WIFI.persistent(false) and that was causing Broken Pipe exception (stream closed) in java.

Java TCP - Client Server help needed

Hi and thanks in advance.
I am currently trying to create a client server program where the server responds to the client based on different requests coming in from the client.
Here is what I am trying to do for the first of the requests (the issue is the same for all of the clients different requests to the server, so fixing just this would help me fix all of them):
1) The client connects to the server
2) The client sends logon information to the server
3) The server checks the logon information for validity
4) The server sends a response saying that login was successful.
5) Client receives and displays response.
Here is the Client (the first try block is located in the client frame, the second within an action listener for a button on the client frame):
try
{
mySocket = new Socket("localhost", 2016);
}
catch (UnknownHostException e1)
{
e1.printStackTrace();
}
catch (IOException e1)
{
e1.printStackTrace();
}
try
{
DOS = new DataOutputStream(mySocket.getOutputStream());
DOS.writeUTF(txtName.getText() + " " + txtPassword.getText());
DOS.flush();
DOS.close();
DataInputStream DISLog = new DataInputStream(mySocket.getInputStream());
JOptionPane.showMessageDialog(null, DISLog.readLine());
}
catch(IOException e1)
{
e1.printStackTrace();
}
Server:
System.out.println("Waiting for client....");
ServerSocket myServerSocket = new ServerSocket(2016);
Socket mySocket = myServerSocket.accept();
myClientHandler = new EZFILEHandler(mySocket);
//Log in check
DataInputStream DISLog = new DataInputStream(mySocket.getInputStream());
StringTokenizer ST = new StringTokenizer(DISLog.readLine());
String Name = ST.nextToken();
String Password = ST.nextToken();
//DISLog.close();
boolean Found = myClientHandler.matchUser(Name,Password);
DataOutputStream DOS = new DataOutputStream(mySocket.getOutputStream());
if (Found == true)
{
DOS.writeUTF("You are logged in.");
DOS.flush();
LoggedIn = true;
}
if (Found == false)
{
DOS.writeUTF("You could not log in.");
DOS.flush();
}
Here is the code for the ClientHandler mentioned in the Server code:
public EZFILEHandler(Socket newConnectionToClient)
{
try
{
mySocket = new Socket("localhost", 2016);
}
catch(Exception e)
{
e.printStackTrace();
}
}
Running the above code will give a Socket is closed exception at this line in the client: DataInputStream DISLog = new DataInputStream(mySocket.getInputStream());, so I then tried commenting out the line: DOS.close(); in the client to keep the socket open, but that causes the button which calls the client code to freeze the program and points to this line if I terminate the program: JOptionPane.showMessageDialog(null, DISLog.readLine());.
So my question is this: How do I allow the client and server to respond to each other in different ways without the socket closing or the jswing freezing from not being allowed to finish processing?
Also, how would it be possible for me to allow multiple clients to logon to the server and all their requests still be processed safely?
Thank you.
If you are writing a Swing program, your socket communication should be on its own SwingWorker thread.
Let's ignore that, and pretend it is just debugging code, not intended to stay.
DISLog.readLine() will read until it reaches the newline character, or the end of the input stream. The server is executing (say) the following:
DOS.writeUTF("You are logged in.");
DOS.flush();
No newline there. And flush() does not close the stream; it simply ensures all the characters are sent, not left in the buffer to be combine with the next set of characters to send.
Catch-22? Yup! The client is waiting for \n, and the server is waiting for more commands from the client.
Change the client to use readUTF().
Update Looks like you need to change the server to use readUTF() as well. The server is probably not getting past the new StringTokenizer(DISLog.readLine()) call unless the client closes the socket.

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.

Java - Socket - Freeze

i've a minimal server which wait until a client connect ,then he start a thread which will send a reply back to the client, the problem is the reply.
This is the code of the server:
int port = 1234;
ServerSocket servSock = null;
servSock = new ServerSocket(port);
while (true) {
Socket link = servSock.accept();
serverThread st = new serverThread(link);
st.start();
}
This is the code of the run() method of the thread,the one which send the answer back, sk is the socket "link" passed by parameter in the server code
public void run() {
String dato = "";
InputStream i = null;
try {
i = sk.getInputStream();
} catch (IOException ex) {
Logger.getLogger(serverThread.class.getName()).log(Level.SEVERE, null, ex);
}
Scanner input = new Scanner(i);
//i receive the data sent
while (input.hasNext()) {
dato += input.nextLine();
}
// then i send a reply
DataOutputStream outputStream=new DataOutputStream(sk.getOutputStream());
outputStream.writeInt(1);
outputStream.close();
Client side ( only the code which should receive the answer from the server) :
Socket link;
int valid = 0;
String url="localhost";
int port=1234;
link = new Socket(InetAddress.getByName(url), port);
//i've to send some data to the server
PrintWriter output = new PrintWriter(link.getOutputStream(), true);
String a = new String(Base64.encode(mex));
output.println(createXml(tag, a));
output.flush();
//then i need to receive an answer from the server
DataInputStream answerI = new DataInputStream(link.getInputStream());
while(answerI.available()!=0)// but answerI.available() is always equal 0
valid = answerI.readInt();
answerI.close();
output.close ();
link.close();
With this code the istruction valid = answerI.readInt(); is not reached.
Without the while cycle, the client freeze at line : valid = answerI.readInt();
Can anyone help me?
Thank you in advance
I'm guessing that the server is blocked in a call to input.hasNext(). This will return false when the socket is closed, and its InputStream returns -1 to signal the end of the stream. However, the socket is still open. The client can send another line; the Scanner is blocking to see what the client's next move will be.
There are ways to shutdown "half" of a socket, so that the server can tell that the client has closed its sending channel but can still receive a response.
However, this approach is complicated. I suggest a change to the protocol so that the server can determine when it is allowed to respond.
In this protocol you don't need the reply if it is always '1'. Just close the socket. The client should block in a read() which will return -1 when the server closes the socket.

Categories

Resources