TCP android Server not recieving first message from Java TCP client - java

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){
....
}

Related

Android TCP socket doesn't receive data

I am using Android app to communicate, send and receive messages through TCP socket with a PC java application on the same LAN. Below is the code of Asynctask i am using in android to send a message and receive a reply from PC:
public class Client extends AsyncTask<Void, Void, Void> {
Context context;
String dstAddress;
int dstPort;
String msg;
Client(Context context, String addr, int port, String msg) {
this.context = context;
dstAddress = addr;
dstPort = port;
this.msg = msg;
}
String reply = "";
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
BufferedWriter dout = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//send request
dout.write(msg);
dout.flush();
dout.close();
//get response
reply = br.readLine();
br.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// DISPLAY REPLY CONTENT
Handler handler = new Handler(context.getMainLooper());
handler.post( new Runnable(){
public void run(){
Toast.makeText(context, "Server reply: " + reply ,Toast.LENGTH_LONG).show();
}
});
}
}
I am displaying the reply of the PC in a toast in onPostExcecute.
Android sends the message through BufferedWriter, while the java app on PC receives it in a BufferedReader. (working fine, and tested)
The PC sends a response throught a BufferedWriter to the android after receiving the message, where the android receives the reply in a BufferedReader as shown: br.readLine(). (HERE is the problem): According to the PC's app debug the reply is sent successfully without any IOExceptions or errors happening, But at the android side the reply string is empty, looks like it received nothing. I really don't know what am I doing wrong, and hope someone can point out to what i am missing.
Below is the server's thread that handles a client socket, the thread runs basically whenever serversocket accepts a socket:
static class clientThread extends Thread {
Socket s = null;
clientThread(Socket s) //constructor
{
this.s = s;
}
#Override
public void run ()
{
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); //receiving data into a buffered reader
String dataIn = br.readLine(); // reading the buffered data into a string
System.out.println("received: " + dataIn);
//BufferedWriter dout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//dout.write("OK");
//dout.newLine();
PrintWriter dout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(s.getOutputStream())), true);
if(dataIn.equals("Android client"))
{
dout.println("OK");
dout.flush();
System.out.println("OK sent");
}
dout.close();
br.close();
s.close();
}
catch (IOException e)
{ System.out.println("Error occured"); }
}
}
SO to sum up the programs, the android sends the message "Android client" (Which the server receives and prints on the console with no issues), now with the reply, the server sends "OK" with no issues as well, but android side receives nothing.
ALSO, as i mentioned before, if i remove
dout.close();
from android's asynctask after i send the message, the server receives the message ONLY when the program gets terminated, I dont understand why i have to close it in order for the message to be sent successfully.
You are reading lines but you aren't sending lines. Add a line terminator to the message sent by the client, or use BufferedWriter.newLine(); and flush() instead of closing the buffered writer.

java.net.Socket > InputStream > BufferedReader.read(char[]) blocks thread

I'm trying to use BufferedReader.read(char[]) method instead of the easier, but less versatile BufferedReader.readLine() method for receiving an answer from a Server. BufferedReader is used in parallel with BufferedOutputStream and, in the code below, the read(char[]) method blocks everything, the last console output is "new buffer, waiting to read."
Client:
public class MessageSender extends Thread {
private String message;
MessageSender(String message) {
this.message = message;
}
public void run() {
try {
Socket sk = new Socket("192.168.1.4", 3000);
BufferedOutputStream bo = new BufferedOutputStream(sk.getOutputStream());
bo.write(message.getBytes());
bo.flush();
char[] c = new char[100];
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
StringBuffer sb = new StringBuffer();
System.out.println("new buffer, waiting to read.");
int ix = 0;
while (ix != -1) {
ix = br.read(c);
sb.append(new String(c));
}
String message = sb.toString();
System.out.println("reply: " + message);
sk.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Server:
public class MessageReceiver extends Thread {
public void run() {
try {
ServerSocket ss = new ServerSocket(3000);
System.out.println("server socket open");
while (true) {
Socket sk = ss.accept();
System.out.println("new connection");
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
String line = br.readLine();
System.out.println("received line: " + line);
BufferedOutputStream bo = new BufferedOutputStream(sk.getOutputStream());
bo.write("ack".getBytes()); bo.flush(); //bo.close();
sk.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Main:
public class Main {
public static void main(String[] args) {
MessageReceiver mr = new MessageReceiver();
mr.start();
while (true) {
String msg = new Scanner(System.in).nextLine();
MessageSender ms = new MessageSender(msg+"");
ms.start();
}
}
}
Everything works fine as long as the BufferedReader.read is not called. But as the code is right now, the output doesn't seem to get sent to the server.
UPDATE
As answered by #JB Nizet, the problem lies in the server script that uses readLine() and waits for either EOL character or the connection end. Therefore, adding "\n" to the message sent from the client side solved the deadlock:
bo.write((message+"\n").getBytes());
When the server accepts a connection from the client, the first thing it does is:
String line = br.readLine();
So, it blocks until the client sends a complete line of text. The server only knows the line is complete if it reads an EOL character, or if the stream is closed by the client.
When the client starts, the first thing it does is
bo.write(message.getBytes());
And message is a line of text, without any EOL. Then the client does
ix = br.read(c);
so it waits for a response from the server, which is itself waiting for an EOL from the client.
You have implemented a networked deadlock.

Send message to server java

I'm creating chat program. At first, I send message to server from client and server should get message, but the message is not sent to the server until I shut down client.
Here is my code:
Client:
private Socket Client;
private Thread RunClient;
private JButton Send;
private int Port=8000;
private String Host="localhost";
public void init() {//Here we connecting to server
Send=new JButton();
Send.setFont(new Font("Times New Roman", Font.BOLD, 15));
Send.setLocation(575,Text.getHeight()+15);//395
Send.SetBorderColor(Color.cyan);
Send.setForeground(Color.white);
Send.setText("Send");
Send.setSize(30,70);
Send.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
SendButton_Click(e);
}
});
try
{
InetAddress address = InetAddress.getByName(Host);
Client = new Socket(address, Port);
System.out.println("Client started. Port: "+Port+"\n");
}catch(Exception e){
System.out.println("Error:"+e);
}
}
public void SendButton_Click(ActionEvent e) {//Here we sending message to server
String sendMessage = "hi";
try {
sendMessageToServer(Client,sendMessage);//sending message to server
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("Message sent to the server : "+sendMessage);
}
}
private void sendMessageToServer(Socket socket,String message) throws IOException {
BufferedWriter writer = new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream()));
writer.write(message);
writer.flush();
}
Here is server:
private int Port=8000;
public void init() {//Here we starting server and starting thread
try {
serverSocket = new ServerSocket(Port);
System.out.println("Server on. Port: "+Port+"\n");
} catch (IOException e1) {
e1.printStackTrace();
}
RunServer = new Thread() {
public void run() {
ServerLoop();
}
};
RunServer.start();
}
public void ServerLoop() {//here we should receive message..
while(true) {
System.out.println("Server loop");
try
{
Socket clientSocket = serverSocket.accept();
InputStreamReader inputstreamreader = new
InputStreamReader(clientSocket.getInputStream());
BufferedReader bufferedreader = new
BufferedReader(inputstreamreader);
PrintWriter printwriter = new
PrintWriter(clientSocket.getOutputStream(),true);
String line = "";
boolean done = false;
while (((line = bufferedreader.readLine()) != null) &&(!done)){
System.out.println("Received from Client: " + line);
if (line.compareToIgnoreCase("Exit") == 0) done = true;
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
Your server is waiting for a full line, i.e. a String that is terminated with \r, \n, or both. Your client does not send a line ending, thus the server's call to readLine() cannot complete until the stream ends, when the remaining (non-line-terminated) input is returned.
Try sending "hi\n" and it should work.
The readLine() method will wait until it receives a newline character (\n) before returning. This means that the method blocks until the client is disconnected. The solution is simple; change the line in sendMessageToServer() that is
writer.write(message);
to
writer.write(message + "\n");
However, you will not be able to send the server messages containing \n without bugs. To do so, you will have to rewrite your reading code to use character-by-character reading.

Getting a server response via a socket in Java and Android

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.

Server and ServerSocket in one Application: not working

I am trying to write a small program, that opens a server, creates a client that connects to this server and receives a message from it.
This is the Code so far
public static void main(String[] args) {
final ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(12345);
Thread t = new Thread(){
public void run(){
try {
Socket server = serverSocket.accept();
PrintWriter writer = new PrintWriter(server.getOutputStream(), true);
writer.write("Hello World");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
};
t.start();
Socket client = new Socket("localhost", 12345);
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String message = reader.readLine();
System.out.println("Received " + message);
} catch (IOException e1) {
e1.printStackTrace();
}
}
If i run program it keeps waiting in readLine() - so obviously the client does not receive the message from the server.
Has anyone got an idea why this isn' working?
Your reading thread is waiting for a newline in the data stream. Just change the server to use:
writer.write("Hello World\r\n");
and you'll get the result you were expecting. Alternatively, you can just close the server socket, and then readLine will return when it reaches the end of the data stream.
You should put the readline in a loop as follows:
public static void main(String[] args) {
final ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(12345);
Thread t = new Thread() {
public void run() {
try {
Socket server = serverSocket.accept();
PrintWriter writer = new PrintWriter(server.getOutputStream(), true);
writer.write("Hello World");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
};
t.start();
Socket client = new Socket("localhost", 12345);
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
// Check this --------------------------------------------------->
String message = null;
while ((message = in.readLine()) != null) {
System.out.println("Received " + message);
break; //This break will exit the loop when the first message is sent by the server
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
You can read this documentation for further explanation: http://download.oracle.com/javase/tutorial/networking/sockets/

Categories

Resources