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.
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){
....
}
I'm having the following TCP client code:
public static void register(InetAddress ip, int port, String name) {
try {
Socket clientSocket = new Socket(ip, port);
send("reg:" + name);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void send(String str) {
try {
String sentence = str;
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(sentence);
} catch (IOException e) {
Log.e("CONNECT", e.getMessage());
}
}
They both are called in onClicks and i know that for sure.
I also have the following Server code:
public static void main(String argv[]) throws Exception {
String clientSentence;
ServerSocket welcomeSocket = new ServerSocket(9876);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
outToClient.writeBytes("msg: Hello! kalin pedro");
}
}
When trying to send data to the server i don't get an exception, i also know that I'm connected to it because the application is crashing when i terminate the server application. The problem is that the server doesn't receive anything until i terminate the client application. Everything that i have tried to send until that moment is all received from the server at once. I looked at the network activity tab provided by Android Studio and there is a change when sending data, the server just doesn't receive it(or at least i don't see it receive it) until i terminate the client application.
I have a Problem: I have a Socket Client on my Android Phone and a Java Socket Server on my PC. Server -> Android works perfektly, but Android -> Server doesn't work.
This is my sending Method on my Phone:
public void sendMessage(String cmd, String parameter) {
String msg;
if(!parameter.equals(""))
msg = cmd+";"+parameter;
else
msg = cmd+";null";
Log.v(TAG,"Send: "+msg);
DataOutputStream bos;
try {
bos = new DataOutputStream(s.getOutputStream());
bos.write(msg.getBytes("US_ASCII"));
bos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
And this is The receiving on my Server:
#Override
public void run() {
while (isRunning) {
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
String message = dis.readUTF();
System.out.println("#"+this.ID+": Received: "+message);
obs.setID(ID);
obs.proceedMsg(message);
} catch (IOException ex) {
this.isRunning = false;
System.out.println("#"+this.ID+": Closed Instance");
}
}
}
Has anyone an Idea? :)
Thanks
You should use writeUTF on a client side. Your server is expecting UTF as you use readUTF method.
writeUTF writes additional 2 bytes in the beginning which indicate block length. When you use plain write method, you do not supply those bytes and this is the problem.
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.
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.