Java Socket not sending message to the server - java

I have the following client socket for sending a string to the server. The server is not getting message. What could be the prob;em?
public void startClient() throws IOException {
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
InetAddress host = null;
BufferedReader stdIn = null;
try {
host = InetAddress.getByName("172.16.2.97");
socket = new Socket(host, 52000);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser = null;
//ClientHelper.unpackISO();
fromUser = ClientHelper.createISO();
if (fromUser != null) {
//System.out.println("Client - " + fromUser);
out.write(fromUser);
System.out.println("Sent message");
}
while ((fromServer = in.readLine()) != null) {
System.out.println("Server - " + fromServer);
if (fromUser != null) {
//System.out.println("Client - " + fromUser);
out.println(fromUser);
}
}
} catch (ISOException ex) {
Logger.getLogger(ClientDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnknownHostException e) {
System.err.println("Cannot find the host: " + host.getHostName());
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't read/write from the connection: " + e.getMessage());
System.exit(1);
} finally { //Make sure we always clean up
out.close();
in.close();
stdIn.close();
socket.close();
}
}
The method ClientHelper.createISO() return a string which is supposed to be sent to the server. Unfortunately the server is not getting any string. Could the problem be proxy settings. If so how can solve it. Or is it another problem with my code?
What is the problem with my code?

You must flush() the stream after writing to it. Sockets buffer until you get a full packet otherwise

Check the 5th line below, you need to flush your output stream. Otherwise server will not get any packet and you will stuck on your first in.readLine() because its blocking.
fromUser = ClientHelper.createISO();
if (fromUser != null) {
//System.out.println("Client - " + fromUser);
out.write(fromUser);
out.flush(); // FLUSH IT HERE, packet wont be sent until you flush your stream
System.out.println("Sent message");
}
Also add flush after your out.write(fromUser) inside the loop.

Related

java socket programming chat

I'm Playing with a simple Client and Server application using socket, and i attempt to print a message in the console and get a response from the server but nothing shows up, i'm fairly new to sockets so i assume i have a logical error. It's a simple app that i want the client to prompt a user a user for a command (in my case an input string where the server will perform an action based on the 'thcharacter), send it to the server and just display the server response.I'm pretty sure my client isn't correct, can someone points out why i can't write anything from the client console.
package socketProgramming;
import java.io.*;
import java.net.*;
public class MyClient {
#SuppressWarnings("resource")
public static void main(String[] args) {
// TODO Auto-generated method stub
Socket socket= new Socket();
BufferedReader in = null;
String msg;
int port = 2222;
try {
System.out.println("CLient wants to connect on port: "+port);
socket = new Socket(InetAddress.getLocalHost().getHostAddress(), port);
System.out.println("The client is connected");
} catch (UnknownHostException e) {
System.exit(1);
} catch (IOException e) {
System.out.println("connect failed");
System.exit(1);
}
try{
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream output = new PrintStream(socket.getOutputStream());
String text = null;
output.print(text);
while ((text = input.readLine()) != null){
System.out.println("Client "+text);
}
socket.close();
System.out.println("Client Exiting");
}
catch(IOException e) {
System.out.println(e);
}}
}
package socketProgramming;
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String msg = "";
ServerSocket sSocket = null;
Socket clientSocket;
int port = 2222;//Integer.parseInt(args[0]);
try{
sSocket = new ServerSocket(port);
} catch(IOException e){
System.out.println(e);
}
while(true){
try {// listen for a connection from client and accept it.
System.out.println("Server is listenning on host: "
+InetAddress.getLocalHost().getHostAddress() +""
+ " and on port: "
+ port);
clientSocket = sSocket.accept();
System.out.println("Connection accepted");
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// PrintWriter out =
// new PrintWriter(clientSocket.getOutputStream(), true);
PrintStream output = new PrintStream(clientSocket.getOutputStream());
msg = input.readLine();
if(msg != null){
if(msg.charAt(12)=='4'){
System.out.println("reading message "+msg+" ");
output.print("Bye");
sSocket.close();
System.out.println("Server exits");
}else{
if(msg.charAt(12)=='0'){
System.out.println("reading message "+msg+" ");
output.print("OK");
}else if (msg.charAt(12)=='1'){
System.out.println("reading message "+msg+" ");
//Should return IP address
output.print(clientSocket.getInetAddress());
}else if (msg.charAt(12)=='2'){
System.out.println("reading message "+msg+" ");
for(int i = 1; i<=10; ++i){
output.print(i);
output.print(" ");
}
}else if (msg.charAt(12)=='3'){
System.out.println("reading message "+msg+" ");
output.print("GOT IT");
}else{
System.out.println("*******************");
}
}
}
sSocket.close();
System.out.println("Server exits");
}
catch(IOException e) {
System.out.println("accept failed");
System.exit(1);
}
System.out.println("Hello world");
}
}
}
I took some liberties with your code and changed it a bit. It is by no means a perfect version of what you've supplied; however, it should get you pointed in the right direction. These were the problems that were solved:
MyClient was never prompting for user input.
MyServer was sending strings without newlines. MyClient was expecting strings with newlines.
In MyServer, the main socket was being closed at the bottom of the loop. I believe you intended to close the client socket so that the server would loop around and process another client.
In MyServer, you're checking the 13th character of the user's input (because you were indexing the 12th byte (zero based) of the string. I put in brute-force protection against checking the 13th byte of strings that are too short.
Again, I simply corrected certain problems in your code. I may have altered it beyond what your true goals actually are. These examples are intended to get you going on your way...
MyClient.java:
import java.io.*;
import java.net.*;
public class MyClient {
#SuppressWarnings("resource")
public static void main(String[] args) {
// TODO Auto-generated method stub
Socket socket = new Socket();
int port = 2222;
try {
System.out.println("CLient wants to connect on port: " + port);
socket = new Socket(InetAddress.getLocalHost().getHostAddress(), port);
System.out.println("The client is connected");
} catch (UnknownHostException e) {
System.exit(1);
} catch (IOException e) {
System.out.println("connect failed");
System.exit(1);
}
try {
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream output = new PrintStream(socket.getOutputStream());
// Get a line of input from the user.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputFromUser = br.readLine();
// Send that line of input to MyServer.
output.println(inputFromUser);
// Print out the response from MyServer.
System.out.println("SERVER RESPONSE: " + input.readLine());
socket.close();
System.out.println("Client Exiting");
} catch (IOException e) {
System.out.println(e);
}
}
}
MyServer.java:
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String msg = "";
ServerSocket sSocket = null;
Socket clientSocket;
int port = 2222;// Integer.parseInt(args[0]);
try {
sSocket = new ServerSocket(port);
} catch (IOException e) {
System.out.println(e);
}
while (true) {
try {// listen for a connection from client and accept it.
System.out.println("Server is listenning on host: " + InetAddress.getLocalHost().getHostAddress() + "" + " and on port: "
+ port);
clientSocket = sSocket.accept();
System.out.println("Connection accepted");
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// PrintWriter out =
// new PrintWriter(clientSocket.getOutputStream(), true);
PrintStream output = new PrintStream(clientSocket.getOutputStream());
msg = input.readLine();
if (msg != null) {
if (msg.length() > 12 && msg.charAt(12) == '4') {
System.out.println("reading message " + msg + " ");
output.println("Bye");
System.out.println("Server exits");
} else {
if (msg.length() > 12 && msg.charAt(12) == '0') {
System.out.println("reading message " + msg + " ");
output.println("OK");
} else if (msg.length() > 12 && msg.charAt(12) == '1') {
System.out.println("reading message " + msg + " ");
// Should return IP address
output.println(clientSocket.getInetAddress());
} else if (msg.length() > 12 && msg.charAt(12) == '2') {
System.out.println("reading message " + msg + " ");
for (int i = 1; i <= 10; ++i) {
output.println(i + " ");
}
} else if (msg.length() > 12 && msg.charAt(12) == '3') {
System.out.println("reading message " + msg + " ");
output.println("GOT IT");
} else {
System.out.println("*******************");
// Invalid question from client, I guess.
output.println("HUH?");
}
}
// Make sure output is flushed to client. It will be, but
// just in case...
output.flush();
}
// We're done with this client. Close his socket.
clientSocket.shutdownOutput();
clientSocket.close();
System.out.println("Closed client socket");
}
catch (IOException e) {
System.out.println("accept failed");
e.printStackTrace();
System.exit(1);
}
System.out.println("Hello world");
}
}
}
The problem is that nobody is actually sending any lines. This is what your client does:
output.print(text); //sends null
while ((text = input.readLine()) != null){ //waits to receive a line
This last part is where your client stops because it waits for input that the server never sends. So here is where the server stops:
msg = input.readLine(); //waits to recieve a line
It never reads in null because you didn't send a line (e.g. ending with '\n'). You can easily fix this problem by replacing your output.print() calls with output.println() calls, so that your readers know the line has end and can be read in now.

Why is my data missing from my file after transfering it over a socket?

I have the same code written for both server and client when attempting to upload a file to the server or download it from the server.
Downloading from the server works just fine and no data is missing in my file, but for some reason when uploading the file, not all is transmitted.
For instance, the file size on my client is smaller then when it is on the server. Then when it is opened up on the server, not all of it is there (since not all of it was received)
Server:
Algorithm:
Get message from client
Client tells server it wants to send a file (push)
Server reads where to put the file, and then receives the file from the client
public static void GetClientMessage() {
while (true) {
try {
try {
try {
serverSocket = new ServerSocket(PORT_NUMBER);
} catch (IOException ex) {
System.out.println("GetClientMessage():serverSocket:IOException:ex " + ex);
SendBackException(ex.toString()); // Inform client
}
try {
System.out.println("Waiting for client");
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("GetClientMessage():socket = serverSocket.accept():IOException:ex " + ex);
SendBackException(ex.toString()); // Inform client
}
bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
// 1 - Read Line (it is the flag)
flag = brffReadIn.readLine();
// 2 - Handle Flag
HandleClientMessage(flag);
// Make decisions based upon that message
} catch (IOException ex) {
System.out.println("GetClientMessage():IOException:ex: " + ex);
SendBackException(ex.toString()); // Inform client
}
socket.close();
serverSocket.close();
} // Close while loop
catch (IOException ex) {
System.out.println("GetClientMessage:serverSocket.close():IOException:ex " + ex);
}
}
}
public static void HandleClientMessage(String message) {
System.out.println("HandleClientMessage:message: '" + message + "'");
switch (message) {
case "push":
GetClientFile();
break;
case "open_cla":
OpenCla();
break;
case "kill_cla":
KillCla();
break;
case "get":
SendFile();
break;
default:
break;
}
}
// Gets path to where to place file on local
public static String GetPath() {
String filePath = " ";
try {
bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
filePath = brffReadIn.readLine();
System.out.println("Path to place file on local: " + filePath);
} catch (IOException ex) {
System.out.println(("GetPath():IOException:ex: " + ex));
}
return filePath;
}
public static void GetClientFile() {
// Get the location where to place the file on local
fileOnLocal = GetPath();
int count;
try {
File file = new File(fileOnLocal);
// Get the size of the file
long length = file.length();
byte[] bytes = new byte[16* 1024];
InputStream in = socket.getInputStream();
OutputStream out = new FileOutputStream(fileOnLocal);
while ((count = in.read(bytes)) > 0) {
System.out.println("strByteArray: " + strByteArray);
out.write(bytes, 0, count);
}
out.flush();
System.out.println("File Size in bytes: " + file.length());
if (file.length() < 5) {
System.out.println("FileClient:Error:File:" + fileOnLocal + " not found on server");
out.close();
in.close();
socket.close();
file.delete();
System.out.println("File:" + file.getAbsolutePath() + " deleted");
} else {
out.close();
in.close();
socket.close();
}
} catch (IOException ex) {
System.out.println(":FileClient:GetServerFile():IOException:ex:" + ex);
}
}
Client Code:
Client tells the server it wants to "push" a file, then it passes the location where to put it on the server, then transmits the file
public void SendFlagToServer(String flag){
try {
bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
bufOut.write(flag);
bufOut.newLine();
bufOut.flush();
System.out.println(host + ":SendFlagToServer: " + flag);
} catch (IOException ex) {
Logger.Log((host + ":FileClient:SendFileToGetToServer():IOException:ex: " + ex));
}
}
After performing this the bytes are received on the client, but not all of them. Is there something I have coded wrong? Should my byte[] array be a different size? This will be used on Win7 & Win8, and possibly Mac in the future.
Edit: I figured it out. I was trying to send a message followed by a string of bytes too quickly.
This fixed my problem:
SendFlagToServer(fileLocaitonOnServer);
Thread.sleep(1000);
....
You are closing sockets after first client conneciton
socket.close();
serverSocket.close();
Solution:
Once you accept a client socket, create a new Thread with the socket connection and handle all IO operations in that thread
Do not close serverSocket. Once you close serverSocket, no more client socket connections will be accepted.
Can you provide the exception you are getting?

How to retry lost connections for reliable transmissions?

I am sending xml data to server via socket programming. I have found that sometimes when the server is down and the client reports socket timeout, I am unable to send or receive.
I want to handle this exception and try to resend for 3 to 4 times. Should I use Thread.sleep, write in loop, or is there any better approach?
private String sendRequestToChannel(String request) {
String xmlData = null;
BufferedReader rd = null;
BufferedWriter bw = null;
String line = null;
String lineSep = null;
String data = null;
StringBuffer serverData = null;
try {
Socket cliSocket = new Socket();
cliSocket.connect(new InetSocketAddress(HOST, PORT), SOCKET_TIMEOUT);
bw = new BufferedWriter(new OutputStreamWriter(cliSocket.getOutputStream()));
bw.write("POST " + PATH + " HTTP/1.0\r\n");
bw.write("Host: " + HOST + "\r\n");
bw.write("Content-Length: " + request.length() + "\r\n");
bw.write("Pragma: cache\r\n");
bw.write("Cache-Control: private, must-revalidate\r\n");
bw.write("Content-Type: application/x-www-form-urlencoded\r\n");
bw.write("\r\n");
bw.write(request);
bw.flush();
rd = new BufferedReader(new InputStreamReader(cliSocket.getInputStream()));
System.out.println("Step 4 : Getting Input Stream");
serverData = new StringBuffer("");
lineSep = System.getProperty("line.separator");
while ((line = rd.readLine()) != null) {
serverData.append(line);
serverData.append(lineSep);
}
data = serverData.toString();
int index = data.indexOf("<");
if (index != -1) {
xmlData = data.substring(index);
} else {
System.out.println("\r\n \r\n XML Data Not Retrived");
}
} catch (java.net.UnknownHostException uh) {
uh.printStackTrace();
System.out.println("$$$$$$$$$$$$ in sendRequestToChannel : UnknownHostException " + uh.getMessage());
return " in sendRequestToChannel : UnknownHostException " + uh.toString();
} catch (IOException ioe) {
ioe.printStackTrace();
System.out.println("$$$$$$$$$$$$ in sendRequestToChannel : IOException " + ioe.getMessage());
return " in sendRequestToChannel : IOException " + ioe.toString();
} catch (Exception e) {
e.printStackTrace();
System.out.println("$$$$$$$$$$$$ in sendRequestToChannel : Exception " + e.getMessage());
return " in sendRequestToChannel : Exception " + e.toString();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException ex) {
Logger.getLogger(SA_Caesar.class.getName()).log(Level.SEVERE, null, ex);
}
try {
if (rd != null) {
rd.close();
}
} catch (IOException ex) {
Logger.getLogger(SA_Caesar.class.getName()).log(Level.SEVERE, null, ex);
}
bw = null;
rd = null;
line = null;
lineSep = null;
data = null;
serverData = null;
}
return xmlData;
}
The biggest problem an application faces when its remote service goes down is that there's no way at all to predict when it will return, if ever.
You are already using a TCP connection which will retry when faced with short-term unreachable services, but by the time TCP has declared the connection dead, you actually don't increase reliability by automatically trying to re-establish the connection. For example, if it takes two days for the remote server to come back, will your application be able to act as if it had never been down? Will all necessary data be queued during the outage? Will the semantics of a connected system be preserved across a weekend's failure? How about if the remote service is down for 5 days?
The best that you can do from a system perspective is notify the operator that there is a fault which requires attention. This is why we still have operators and will for the foreseeable future.

Connecting a Client to Multiple Servers in Java

I want a client to connect to more than one server. i.e. I want my client to send a number to server1 which squares the number and echoes it back to the client. However I want the client to then send this squared number to a second server listening on a different port.
I'm not sure how to implement this functionality, could I do this through threads or would I just open a second socket to server2?
Here is the code for my client.
import java.io.*;
import java.net.*;
public class ClientA {
public static void main(String[] args) {
String serverhost = "localhost";
int serverport = 6789;
Socket clientSocket = null;
DataOutputStream os = null;
BufferedReader is = null;
try {
clientSocket = new Socket(serverhost, serverport);
os = new DataOutputStream(clientSocket.getOutputStream());
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + serverhost);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + serverhost);
} //end try
if (clientSocket == null || os == null || is == null) {
System.err.println( "An error has occured, please restart." );
return;
} //end if
try {
while ( true ) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String keyboardInput = br.readLine();
os.writeBytes( keyboardInput + "\n" );
int n = Integer.parseInt( keyboardInput );
if ( n == 0 ) {
break;
}
String responseLine = is.readLine();
System.out.println("Server returns its square as: " + responseLine);
}
os.close();
is.close();
clientSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
} //end try
} //end main
} //end class
Based on the info you've given, I don't see the need to make it a multi-threaded application as you're only sending (i.e. not receiving) data to the second server when you receive a reply from the first server. Just set up a second socket to the other address and send the data when you get it from the first server.

Java two- way socket connection (server/ client)

what I'm trying to do is to send some JSON from an Android phone to a Java server, which works fine. The Android/ client side looks like this:
Socket s = new Socket("192.168.0.36", 12390);
s.setSoTimeout(1500);
JSONObject json = new JSONObject();
json.put("emergency", false);
json.put("imei", imei);
json.put("lat", l.getLatitude());
json.put("lon", l.getLongitude());
json.put("acc", l.getAccuracy());
json.put("time", l.getTime());
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
out.write(json.toString());
out.flush();
s.close();
The server side is this:
try {
s = new ServerSocket(port);
}
catch (IOException e) {
System.out.println("Could not listen on port: " + port);
System.exit(-1);
}
Socket c = null;
while (true) {
try {
c = s.accept();
} catch (IOException e) {
System.out.println("Accept failed: " + port);
System.exit(-1);
}
try {
BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
String inputLine = null;
String result = "";
while ((inputLine = in.readLine()) != null) {
result = result.concat(inputLine);
}
System.out.println(result);
As I said, all of that works. Now I want to send a message back from the server to the client after it received the message from the client.
I extended the code like this, Android/ client side:
Socket s = new Socket("192.168.0.36", 12390);
s.setSoTimeout(1500);
JSONObject json = new JSONObject();
json.put("emergency", false);
json.put("imei", imei);
json.put("lat", l.getLatitude());
json.put("lon", l.getLongitude());
json.put("acc", l.getAccuracy());
json.put("time", l.getTime());
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
out.write(json.toString());
out.flush();
String inputLine = null;
String result = "";
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
while ((inputLine = in.readLine()) != null) {
Log.d(TAG, in.readLine());
result = result.concat(inputLine);
}
And the server side:
try {
s = new ServerSocket(port);
}
catch (IOException e) {
System.out.println("Could not listen on port: " + port);
System.exit(-1);
}
Socket c = null;
while (true) {
try {
c = s.accept();
} catch (IOException e) {
System.out.println("Accept failed: " + port);
System.exit(-1);
}
try {
BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
String inputLine = null;
String result = "";
while ((inputLine = in.readLine()) != null) {
result = result.concat(inputLine);
}
System.out.println(result);
PrintWriter out = new PrintWriter(c.getOutputStream());
out.write("Hello phone");
out.flush();
out.close();
On the client side, nothing ever comes in, it hangs on
while ((inputLine = in.readLine()) != null) {
Log.d(TAG, in.readLine());
result = result.concat(inputLine);
}
until the socket times out (never enters the loop). I thought it might be a timing problem, for example the server sending out its reply too early and therefore the client never receiving anything, but i tried to put the out.write("Hello phone"); pretty much anywhere in the code, always the same result. Can it have to do with the socket being obtained from ServerSocket and not being able to send out data? What am I missing here, this is bugging me all day ...
Edit: After Nikolais answer, I tried this (client):
out.write(json.toString());
out.newLine();
out.write("###");
out.flush();
String inputLine = null;
String result = "";
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
while ((inputLine = in.readLine()) != null) {
if (inputLine.contains("###")) {
break;
}
Log.d(TAG, in.readLine());
result = result.concat(inputLine);
}
s.close();
and server:
while ((inputLine = in.readLine()) != null) {
result = result.concat(inputLine);
if (inputLine.contains("###")) {
System.out.println("received ###");
out.println("Hello phone");
out.println("###");
out.flush();
break;
}
}
The idea was to send out the message from the server before the client closes the socket. Still doesnt work ... any hints?
On the server side you never get to sending your "Hello phone". Not until client closes the socket, but at that point it's useless. This is because in.readLine() blocks until either data is available or EOF, i.e. socket closed.
You need a way to get out of the reading loop - invent (or adopt) some application-level protocol that would tell you that a whole message is received. Common options are fixed length messages, length prefix, delimited, etc.

Categories

Resources