java calling method outputs nothing - java

I have a method which takes an IP, receives data and stores it in a List. At the end of the method it returns this List. However when this method is called, the list is empty. I think it is a really simple fix and it's me being stupid but could anyone point me to where I have gone wrong so I dont do it again?
public List<String> receiveDataFromOperator(){
List<String> dataRec = new ArrayList<String>();
try
{
System.out.println("Client Program");
//Hard coded IP Address
String ip = "146.176.226.147";
//Hard coded port
int port = 500;
// Connect to the server
Socket sock = new Socket(ip, port);
// Create the incoming stream to read messages from
DataInputStream network = new DataInputStream(sock.getInputStream());
// Display our address
System.out.println("Address: " + sock.getInetAddress());
String line;
// Loop until the connection closes, reading from the network
while ((line = network.readUTF()) != null)
{
dataRec.add(line);
}
sock.close();
}
catch (IOException ioe)
{
//Test output for the arraylist size
System.out.println(dataRec.size());
for(int i = 0; i<dataRec.size(); i++){
System.out.println("Line " + i + dataRec.get(i) + "\n");
}
}// End of catch
return dataRec;
}//End of method

If the server is writing binary data with DataOutputStream.writeUTF() it should work.
If you are sending text from the server you need to read text from the socket with BufferedReader.readLine().
BTW: When you get an IOException you generally shouldn't ignore it and pretend it didn't happen esp. when the program is not behaving as you expect.

Related

What is a good way to handle command read from user and server's response in a remote command-line interpreter?

I'm implementing a client side software that lets user input commands, sends them to a server, the server interprets them and sends the result to the client. Here's where I'm stuck, I have a while loop that gets responses from server until the connection ends.
try(Socket socket = new Socket(hostname, port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))){
System.out.println("Connected to " + hostname + ":" + port + " !");
Scanner scanner = new Scanner(System.in);
String command = scanner.nextLine();
String fromServer = null;
int status;
HashMap<String, String> response;
long start = 0;
System.out.println("C:" + command);
if (command.toLowerCase().equals("exit")) return;
out.println(command);
if (command.toLowerCase().equals("shutdown")) return;
out.println();
while ((fromServer = in.readLine()) != null) {
// Here's my problem
response = parseResponse(fromServer);
if (response.containsKey("response")) response.put("response", response.get("response").replaceAll("\\\\n", "\n"));
try {
status = Integer.parseInt(response.get("status"));
} catch (NumberFormatException e){
status = Status.RESPONSE_CORRUPTED;
}
System.out.println("S:" + status + (response.get("response") != null ? "\n" + response.get("response") : ""));
command = scanner.nextLine();
System.out.println("C:" + command);
out.println(command);
}
} catch (IOException e){
System.out.println("Server isn't connected, try again later.");
}
The real problem is that I need to put
if (command.toLowerCase().equals("exit")) return;
out.println(command);
if (command.toLowerCase().equals("shutdown")) return;
out.println();
before the while, so there's three out.println() in the code while one would be more "logic" and I need to put
if (command.toLowerCase().startsWith("shutdown") && fromServer.equalsIgnoreCase("0") || status == Status.RESPONSE_CORRUPTED) break;
in that while so the client stops directly when the command shutdown is sent (to shutdown the server) to prevent the user from entering another command.
I'm searching for a more efficient way to manage commands and to add a ping command (but I need to add an if before the one to shutdown), maybe using more OOP but I don't see how to do it.
I think you should give a try to Spring Shell first before attempting to make your own from scratch. It is quite modular and you can create the backend handlers that send the commands to the remote server.
Use an infinite loop and break it based on the user input or on the server response
Here is an example which does not send the exit/shutdown commands to the server, but rather they only stop the client. If you need to send all the commands to the server and stop only based on the server response then just delete the if statement from the while loop
Scanner scanner = new Scanner(System.in);
String command = null;
while (true) {
command = scanner.nextLine();
if (command.toLowerCase().equals("exit") || command.toLowerCase().equals("shutdown")) {
break;
}
out.print(command);
out.flush();
String response = in.readLine();
// do something with the response (ex. stop the client by calling break or just print the response
}

Creating an echo-server: Connected client gets IO-exception

I'm trying to create a single-threaded echo-server, but I can't figure out how to send the input from the client back to the client again from the server. The client connects to the server alright, but it's when it's waiting for a response that it throws an IOException. I have tried connecting my chat client to other chat servers, hence I'm sure the fault is in the chat server implementation.
I'm guessing the "villain of the piece" is this method presented below that takes the input from the connected client and sends it back, but I'm not sure why it doesn't work.
private void processClientRequest(Socket clientSocket) throws IOException {
InputStream in = clientSocket.getInputStream();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream());
long time = System.currentTimeMillis();
out.write("Server - " + time + ": " + in);
out.close();
in.close();
}
Please tell me if this method isn't the issue and you need other parts of my code instead.
Thanks in advance!
Edit: I have now managed to get my server to respond to the client. I did this by changing the processClientRequest method to this:
try {
BufferedReader in =
new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream());
long time = System.currentTimeMillis();
out.write("Server - " + time + ": " + in.readLine());
out.close();
try {
in.close();
} catch (IOException e) {
System.err.println("Couldn't close input stream");
}
} catch(IOException e) {
System.err.println("Got an IOException error while reading or writing from/to client");
}
But as of now my server can only respond the client once. If the client writes to the server a second time it does get a response, but instead of the clients message, it's "null". And since I want my echo server to be able to answer the client until the client shuts down or something like that, I need to figure out how to change that. I figure I'm going to need some kind of while loop to make this happen, but I have tried for example putting the whole try statement into an infinite while loop, but that just gave me loads of IOExceptions.
You're not reading the clients input. You're just passing the toString to your out. You need to make a while loop and read from in. Maybe in a seperate thread unless you're sure the input is short. In test code should be okay:
private void processClientRequest(Socket clientSocket) throws IOException {
InputStream in = clientSocket.getInputStream();//wrap this in a object stream or other to read lines/ utf
int i = 0;
while(i++ < 1000 && in.available() > 0){
int read = in.read();//use it if u want, like to a string builder declared out of loop and echo it back after u read input
}
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream());
long time = System.currentTimeMillis();
out.write("Server - " + time + ": " + in);
out.close();//should be in seperate try catches so if 1 close fails u still close other and finally close socket in 3rd try catch
in.close();
}
Socket server with working echo server, mini web server and helpful in many more ways.

file transfer between server and client input stream

I'm working on a java server-client based file transfer over socket project, I'll sum up the project shortly, I have text files related to server and client, server related text contains which ports are going to be opened and client text contains the IP and port to be connected on(server side is like 4444 and client side is like 4444 localhost) The file transfer on a single client is running pretty ok, now I'm working on second client connection and transfer, what I'm trying to do is; when a second client is run, it will read the first line of the text file (which is already in use by the first client), I thought a recursion will solve the problem but seems I couldn't figure out what I've done wrong, below are the code snippet from client side
boolean connected = false;
private void connection() {
while (!connected) {
try {
FileReader fr = new FileReader("c_input.txt");
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
String delims = "[ ]";
String[] elements = new String[8];
elements = line.split(delims);
serverPort = Integer.parseInt(elements[portIndex]);
hostIP = elements[ipIndex];
clientSocket = new Socket(hostIP, serverPort);
is = clientSocket.getInputStream();
if (is != null) {
connected = true;
System.out.println("connected to " + hostIP + " from port "
+ serverPort);
br.close();
fr.close();
} else {
System.out.println("The port " + serverPort
+ " is occupied, now trying another port.");
portIndex = portIndex + 2;
ipIndex = ipIndex + 2;
connection();
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
}
I used recursion there, because if a port is bound by another client it has to read another line from text file and split and retry connection with the new line's inputs.(in terms short the whole method will run again) But when it comes to running, the first client connects and when second one tries to connect from same port with client1 the code still gets in if loop instead of getting in else block (I get the message from the if check's println on the console and by the way is in the if check stands for InputStream) which means there is a stream coming from server, is this normal? if so how can I achieve the whole thing connection method does all over again if the port is bound by another client?

What determines in this code what is sent back to the client? TCP Sockets

In the code below, what determines what will be sent back to the client (the PHP page). I am trying to alter this so that it sends a variable back to the PHP page with an error message that is defined based on actions made in my java code.
Edit: To answer some questions, what I am trying to do is this.
Send a string to the java script with a socket and convert it to a variable to be used in the java script. It will run through some if statements and I need to set the error statements to a variable lets say "reply". I need to send "reply" then back to the PHP file.
public class MyJavaServer {
public static void main(String[] args) {
int port = 20222;
ServerSocket listenSock = null; //the listening server socket
Socket sock = null; //the socket that will actually be used for communication
try {
listenSock = new ServerSocket(port);
while (true) { //we want the server to run till the end of times
sock = listenSock.accept(); //will block until connection recieved
BufferedReader br =
new BufferedReader(new InputStreamReader(sock.getInputStream()));
BufferedWriter bw =
new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
String line = "";
while ((line = br.readLine()) != null) {
bw.write("PHP said: " + line + "\n");
bw.flush();
}
//Closing streams and the current socket (not the listening socket!)
bw.close();
br.close();
sock.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
If I get your question right, the line where the answer gets sent to the peer is
bw.write("PHP said: " + line + "\n");
which writes the given string to bw.

java TCP socket message breaks

i have a java client-server app in java, both using the same connection class that contains both send/receive messages.
for some reason, some of the messages i send are received in a malformed order:
here's the code
//set up
_in = new BufferedReader(new InputStreamReader(this._socket.getInputStream()));
_out = new BufferedWriter(new OutputStreamWriter(this._socket.getOutputStream()));
this._socket.setSoTimeout(S_TIMEOUT);
public synchronized boolean send(String message){
try {
_out.write(message);
_out.write(Connection.DELIMITER);
_out.flush();
return true;
} catch (IOException e) {
}
return false;
}
public String receive(){
int c;
try {
String message = "";
System.out.println("Getting message:");
c = _in.read();
while(c != -1 && c != Connection.DELIMITER) {
message += (char) c;
c = _in.read();
}
if (c == -1) {
return null;
}
return message;
} catch (IOException e) { }
return null;
}
some messages, for example "new_order" will might return with "ew_ord".
some characters are lost, others are sent separately. this seems odd as its TCP
could this be an encoding related issue?
Delimiter is (char) 0
socket timeout is 20000 (ie 20 senconds). every 10 seconds i send an empty message to make sure socket does not close
EDIT:
although it was solved using the Scanner, i must say that the original code worked fine for many messages/various machines for a very long time (a few weeks), and then suddenly failed to work with one specific message on one specific machine (other messages went through just fine). i've done socket data transfer in java MANY times and i've written many read/write methods to handle the sockets. it's the first time i ran into this.
although in the original code i set the encoding (in the posted code i didn't), i believe that the problem was encoding related. at one point, the message that was received had every second character missing. afterwards i changed it a bit, and the first/second character of the message were received in a separate message. from my understanding, it's either an encoding issue or some firewall/other security program that was running on the message sender machine, that decided to filter outgoing packets.
Try replacing your receive with a Scanner and let it do the work for you.
// in your setup
Scanner sc = new Scanner(_in).useDelimiter(Connection.DELIMETER);
public String receive() {
try {
return sc.next();
} catch(IOException e) {
return "";
}
}
For starters, I would make sure you're printing exceptions in those catch blocks.
Then, you're using the platform default encoding for converting characters to bytes. If these two processes are running on different machines, it's possible they're using different encodings. I would make sure you're specifying an encoding when you set up the Reader and Writer.
You can use UTF encoding for getting Full String of Message.
U can try this code and I am Sure About this code because i used it in My Chat Application.
String data=" ";
socket = new Socket("localhost",999);
while(true)
{
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
data = dis.readUTF();
jta.append(data +"\n");
}
Where jta is JTextArea.
It's for Client Side
Now For Server Side:
try
{
server = new ServerSocket(999);
Socket soc = server.accept();
while(true)
{
String data="";
try
{
dis = new DataInputStream(soc.getInputStream());
dos = new DataOutputStream(soc.getOutputStream());
data = dis.readUTF();
}
catch(Exception e)
{ }
jta.append(data + "\n");
}
}
catch (IOException e)
{
JOptionPane.showMessageDialog(this, e);
System.exit(-1);
}

Categories

Resources