I'm trying to write an Android client and a Java server.
It works to send a message from the Android client to the server (if the testing code is commented out), but I cannot get the response back from the server to the client.
Could you please help me?
Here's the client:
public class MainActivity extends Activity {
private PrintWriter printwriter;
private EditText textField;
private TextView textView;
private Button button;
private String message;
private String serverResponse;
String fromServer;
Socket clientSocket;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textField = (EditText) findViewById(R.id.editText1);
textView = (TextView) findViewById(R.id.textView);
button = (Button) findViewById(R.id.button1);
final String hostName = "10.111.207.253";
final int portNumber = 4444;
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
message = textField.getText().toString();
textField.setText("");
new Thread(new Runnable() {
public void run() {
try {
clientSocket = new Socket(hostName, portNumber);
printwriter = new PrintWriter(clientSocket.getOutputStream(),true);
printwriter.write(message);
// testing only - trying to get the response back from the server
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while(true) {
if ((serverResponse = in.readLine()) != null) {
Log.i("server says", serverResponse);
break;
}
}
// testing only
printwriter.flush();
printwriter.close();
clientSocket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
textView.setText("Server: " + serverResponse);
}
});
}
}
And here's the server:
public class MyServer {
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
}
System.out.println("Server started. Listening to the port 4444");
while (true) {
try {
clientSocket = serverSocket.accept(); //accept the client connection
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); //get the client message
message = bufferedReader.readLine();
if (message != null) {
System.out.println("Client says: " + message);
//testing only
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
out.println("response from server");
//testing only
inputStreamReader.close();
clientSocket.close();
}
} catch (IOException ex) {
System.out.println("Problem in message reading");
}
}
}
Please help!
You've inserted code to read a reply from the server before you flush your client's PrintWriter. You're not using println() so the boolean you passed to the constructor to enable autoflush doesn't apply as stated in the javadoc:
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.
This means the client is never sending anything, therefore the server never receives anything. Back in the client you'll block forever waiting for a reply that is never coming.
Either use printwriter.println() to send your message, or move printwriter.flush() to before you attempt to read a reply from the server.
Related
I have a TCP Client in java and TCP server in android. Sending message form Server to Client works fine but when message is sent from Client to server(android) it doesn't shows the message but when same process is repeated second time, server shows the message i.e send button of java client should be pressed twice then only message is shown in the android app.
Java Client Code
//btn handelar to send message form textarea
private class ButtonHandler implements ActionListener
{
public void actionPerformed (ActionEvent event)
{
String outputLine = txArea.getText ();
System.out.println ("Client > " + outputLine);
out.println (outputLine);
out.flush();
}
}
//receiving message
public void run () throws IOException
{
Socket socket = new Socket ("192.168.123.3",1234);
BufferedReader in = new BufferedReader (new InputStreamReader (socket.getInputStream ()));
out = new PrintWriter (socket.getOutputStream (), true);
String inputLine;
while ((inputLine = in.readLine ()) != null)
{
System.out.println ("Client < " + inputLine);
rxArea.setText (inputLine);
}
out.close();
in.close();
socket.close();
}
Android Server Code
public void runTcpServer(){
handel = new Handler();
try {
int a = Integer.parseInt(new SettingDialog().port);
//creating a socket to listen on a given port
Log.i("NW LOG","PORT OPENED SUCESSFULLY in "+a);
final ServerSocket serverSocket = new ServerSocket(a);
Thread listenConnection = new Thread(new Runnable() {
#Override
public void run() {
try {
//accepting the incoming socket connection request
Socket workstationSocket = serverSocket.accept();
//reading the incoming content
BufferedReader readerIn = new BufferedReader(new InputStreamReader(workstationSocket.getInputStream()));
outMessage = new PrintStream(workstationSocket.getOutputStream(),true);
Log.i("NW LOG","WATING FOR MSG");
while(readerIn.readLine()!=null){
final String incomingMsg = readerIn.readLine();
//setting incoming message to UI thread using handler
handel.post(new Runnable() {
#Override
public void run() {
setMessage(IN,incomingMsg);
}
});
}
outMessage.close();
readerIn.close();
workstationSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});listenConnection.start();
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is the following code part:
while(readerIn.readLine()!=null){
final String incomingMsg = readerIn.readLine();
....
In the first line you are reading the line and ignoring it. Therefore you are throwing away every second line.
The correct way to read and use it for the while loop is this:
String incomingMsg;
while((incomingMsg = readerIn.readLine())!=null){
....
}
Here's the problem. I'm attempting to set up a very simple app that will send messages to a Java server.
Here is my server code:
ServerSocket serverSocket = null;
Socket clientSocket =null;
try
{
serverSocket = new ServerSocket(4444);
System.out.println("Server Started...");
clientSocket = serverSocket.accept();
}catch(Exception e){};
Scanner in = new Scanner(clientSocket.getInputStream());
String inputLine;
while (true)
{
if(in.hasNext())
{
inputLine=in.nextLine();
System.out.println("Message from server: "+inputLine);
}
}
And here's the client code:
Socket client;
PrintWriter printwriter;
String serverIpAddress="192.168.173.1";
Button button;
TextView text;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button =(Button) findViewById(R.id.button);
text=(TextView) findViewById(R.id.textView);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
client = new Socket(serverIpAddress,4444);
printwriter = new PrintWriter(client.getOutputStream());
printwriter.write("Start");
printwriter.flush();
//printwriter.close();
//client.close();
}
catch(UnknownHostException e)
{
}
catch(IOException e)
{
e.printStackTrace();
}
}
}).start();
}
});
}
I have one button, when I press it a message is sent to the server and it displays fine, but when I press the button the socket does not reconnect so I can't send the massage again.
To be clear I intend to eventually add more buttons to send different messages. I looked into creating a global socket but that didn't seem to go anywhere.
Any help is greatly appreciated.
This is because you are not closing the socket in the client code. You should close the streams & sockets in both server and client when the connection is over. Saying this, you should keep the connection alive and send several messages instead of closing the connection after sending one message.
I would for example rewrite the server code as (please note that this handles only one client):
ServerSocket serverSocket = null;
Socket clientSocket =null;
Scanner in = null;
try
{
serverSocket = new ServerSocket(4444);
System.out.println("Server Started...");
clientSocket = serverSocket.accept();
in = new Scanner(clientSocket.getInputStream());
String inputLine;
while (true) {
if(in.hasNext()) {
inputLine=in.nextLine();
System.out.println("Message from server: "+inputLine);
}
}
} catch(IOException e) {
e.printStackTrace();
} finally {
if(in != null) {
in.close();
}
if(clientSocket != null) {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Just a note: I would use DataInputStream & DataOutputStream... in this way, you could use in.readUTF() in the server side which will block until receiving something new through network. In this way, you will not have to do while(true) which will be way much better for the CPU.
Thank you all for your responses. I did get it working.
Multithreader, thank you, you were completely correct about where my problem lay. I did it a bit differently though.
I set up another class to set up the socket and created a method to start listening on the given port. In the main I just put that in a loop to keep closing and recreating the socket till the end condition is met.
Thanks again all.
I want to transfer data from Android device to the java desktop server. I have a text and button. As I press the button on the device, the text should be displayed on the java desktop server. I also have added AsyncTask in the client. The error code has also been added. The port i have used is 4444 and the ip address I used is of my local host address.
I am doing a very silly mistake. Can you please guide me.
I run the server code, it first gives me : Server started. Listening to the port 4444.
Now, I run the client code and write something on my mobile. As I press my button, it gives me error. And the app crashes and closes. I am a new one. Thanks in advance.
Client Code :
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textField = (EditText) findViewById(R.id.editText1); //reference to the text field
button = (Button) findViewById(R.id.button1); //reference to the send button
//Button press event listener
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
messsage = textField.getText().toString(); //get the text message on the text field
textField.setText(""); //Reset the text field to blank
try {
client = new Socket("134.190.162.165", 4444); //connect to server
printwriter = new PrintWriter(client.getOutputStream(),true);
printwriter.write(messsage); //write the message to output stream
printwriter.flush();
printwriter.close();
client.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public class Asynctask extends AsyncTask<View, Integer, Socket>
{
private static final String IP_ADDRESS = "134.190.162.165"; // Toshiba laptop
// private static final String IP_ADDRESS = "10.0.0.2"; // Toshiba laptop
private static final int DEST_PORT = 4444;
private EditText mTextField;
/**
* Store provided views (used later in onPostExecute(...)).
*
* Create socket to communicate with server (blocking call).
*/
protected Socket doInBackground(View... params)
{
// Store provided views.
if (params.length != 1)
throw new IllegalArgumentException();
mTextField = (EditText) params[0];
// Create socket.
Socket client = null;
try
{
client = new Socket(IP_ADDRESS, DEST_PORT); // connect to server
} catch (UnknownHostException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return client;
}
/**
* Write to server.
*/
protected void onPostExecute(Socket client)
{
try
{
PrintWriter printwriter;
String messsage;
messsage = mTextField.getText().toString(); // get the text message on the text field
mTextField.setText(""); // Reset the text field to blank
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(messsage); // write the message to output stream
printwriter.flush();
printwriter.close();
client.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
Server Code:
public class server {
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(4444); //Server socket
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
}
System.out.println("Server started. Listening to the port 4444");
while (true) {
try {
clientSocket = serverSocket.accept(); //accept the client connection
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); //get the client message
message = bufferedReader.readLine();
System.out.println(message);
inputStreamReader.close();
clientSocket.close();
} catch (IOException ex) {
System.out.println("Problem in message reading");
}
}
}
}
The error which I get is:
FATAL EXCEPTION: main
android.os.NetworkOnMainThreadException
android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
libcore.io.IoBridge.connectErrno(IoBridge.java:127)
libcore.io.IoBridge.connect(IoBridge.java:112)
java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
java.net.Socket.startupSocket(Socket.java:572)
java.net.Socket.tryAllAddresses(Socket.java:127)
java.net.Socket.<init>(Socket.java:177)
java.net.Socket.<init>(Socket.java:149)
com.example.client.MainActivity$1.onClick(MainActivity.java:42)
android.view.View.performClick(View.java:3567)
In the manifest file, I have added all the requirements. It does not give any compile time error.
I checked from many websites but the code which is working is this only. But I dont know where I am making mistake in running it or somewhere else.
If any other option is there, please suggest me, i am scratching my head since long
Thanks
Your code seems very confusing. The client seems to have code for doing the network connection and I/O both on the main thread (in the OnClickListener attached to button) and in the AsyncTask (which is never created). Try this for an OnClickListener:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
message = textField.getText().toString(); //get the text message on the text field
textField.setText(""); //Reset the text field to blank
new Asynctask().execute(message);
}
});
But you have another problem: while your AsyncTask is (correctly) making the socket connection in doInBackground, it is incorrectly doing the network I/O in onPostExecute. The network I/O also needs to be done in the background. Try this for an AsyncTask:
public class Asynctask extends AsyncTask<String, Void, Void> {
private static final String IP_ADDRESS = "134.190.162.165"; // Toshiba laptop
// private static final String IP_ADDRESS = "10.0.0.2"; // Toshiba laptop
private static final int DEST_PORT = 4444;
private EditText mTextField;
/**
* Store provided views (used later in onPostExecute(...)).
*
* Create socket to communicate with server (blocking call).
*/
protected Void doInBackground(String... messages) {
if (messages.length != 1) { return null; }
String message = messages[0];
// Create socket.
Socket client = null;
try {
client = new Socket(IP_ADDRESS, DEST_PORT); // connect to server
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Write to server.
try {
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(messsage); // write the message to output stream
printwriter.flush();
printwriter.close();
}
catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The above is entirely untested, so it may not be exactly right. I also didn't look at your server code; this answer just addresses the NetworkOnMainThreadException problem.
I have to do a very simple TCP server that listens to some client using TCP and returns the message in upper case.
The connection stablishes fine, the client sends messages perfectly and the server listens to them but the server won't answer and I don't have a clue of why is this happening...
Server:
//imports and stuff you don't really care about
public class ServerThread extends Thread {
private final Socket clientSocket;
private final Main controller;
private final Server server;
BufferedReader in;
PrintWriter out;
//constructor
ServerThread(Socket clientSocket, Main controller, Server server) throws IOException {
this.clientSocket = clientSocket;
this.controller = controller;
this.server = server;
//make input and output streams
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//THIS MAY BE WRONG
out = new PrintWriter(clientSocket.getOutputStream());
}
#Override
public void run() {
controller.out("Connected: " + clientSocket.getInetAddress().toString());
out.println("test");
try {
String msg;
while ((msg = in.readLine()) != null) {
//Prints this line
System.out.println(clientSocket.getInetAddress().toString() + " says: " + msg);
//THIS MAY BE WRONG
out.println(msg.toUpperCase());
System.out.println("Answered");//this line too
}
}catch(SocketException ex){
destroyMe();
}
catch (IOException ex) {
Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
destroyMe();
}
}
//couple of methods that don't interfere here
}
Client:
public class Client extends Thread {
private final String host = "localhost";
private final int port = 44444;
private final PrintWriter out;
private final Socket socket;
BufferedReader in;
private Main c;
public Client(Main c) throws IOException {
this.c = c;
socket = new Socket(host, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Connection Opened.");
}
public void send(String str) {
out.println(str); //this works fine
}
#Override
public void run() {
String msg;
while (true) {
try {
//THIS MAY BE WRONG but I don't think so
while ((msg = in.readLine()) != null) {
System.out.println("received: " + msg); //this never happens
c.out(msg);
}
//this line is always reached until I close the connection.
} catch (SocketException ex) {
System.out.println("Connection closed"); //this line is reached too
break;
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
//This works fine
}
}
}//end of the thread
//there are a couple of methods here but they don't do anything related
}
I don't see anything wrong but something must be.
Thanks for your help.
You are using a PrinterWriter to control the output of your Server code.
You are creating it without automatic flushing turned on via out = new PrintWriter(clientSocket.getOutputStream()); Automatic flushing when turned on, per the documentation, will occur when you write a message via the println, printf, or format methods.
Either turn on automatic flushing & use the above methods to write you message, call the flush method when you want to send a message, or use a different method altogether to control your Server output stream.
http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html
I have an android application that I am attempting to use to send and receive messages to a server using socket connection.
I have had all manner of problems sending and receiving. I have been able to do one or the other, at no point both.
I was wondering if someone could help me with a simple exercise that I can compile using BufferedReader and PrintWriter to do so.
I appreciate any help as I am at the point of giving up.
Thanks in advance.... Below are a few shots of what I have tried (Though they are irrelevant to this question, I hope it shows that I have tried before asking here).
private OnClickListener sendClickListener = new OnClickListener(){
public void onClick(View arg0) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}};
public class ClientThread implements Runnable {
public void run() {
try {
EditText dstAddress = (EditText) findViewById(R.id.destinationAddress);
EditText dstMessage = (EditText) findViewById(R.id.messageToTranslate);
EditText dstPort = (EditText) findViewById(R.id.destinationPort);
String address = dstAddress.getText().toString();
String message = dstMessage.getText().toString();
int port = Integer.parseInt(dstPort.getText().toString());
InetAddress serverAddr = InetAddress.getByName(address);
Log.d(".Coursework", "C: Connecting...");
Socket socket = new Socket(serverAddr, port);
connected = true;
while (connected) {
try {
EditText dstTranslation = (EditText) findViewById(R.id.returnedTranslation);
dstTranslation.setText("help me");
Log.d(".Coursework", "C: Sending command.");
PrintWriter out;
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(language);
out.println(message);
Log.d("ClientActivity", "C: Sent.");
//BufferedReader in;
//in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//String translation = in.readLine();
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
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+"\n");
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();
System.out.print(translatedMessage);
br.close();
//Log.d("application_name",translatedMessage); Trying to check the contents begin returned from the server.
return "Say What??";
}
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
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 \n"); // Test message!
pw.flush();
// Send off the data
pw.close();
br.close();
clientSocket.close();
serverSocket.close();
}
}
}
I simply neglected to close the socket connection on the client side. So whilst I doubt what I have done is a model answer to my own question it works of included.