Socket connection not closing in android in while loop - android

I am developing an app where I connect via a socket to get data from the, but once I establish a socket connection invoked via a button click, I can see that I am able to connect and get the data, but the socket connection doesn't terminate and the app hangs. I have included socket.close(); in my code but it isn't helping below is my code snippet..
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/// some code which isn't important here
// establish socket connection to get data
try{
Socket s = new Socket("IP",portnumber);
Log.d(TAG, "socket connected");
PrintWriter out1 = new PrintWriter(s.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out1.println(value1);
Log.d(TAG, value1);
String line="";
String msg = "";
while ((line=in.readLine()) != "//end of message from server")
{
msg+=line+"\n";
Log.d(TAG, msg);
}
out1.close();
in.close();
s.close();
Log.d(TAG, "socket closed " );
}
catch (IOException e) {
Log.e(TAG, "file finished " + e.getMessage());
}

It hangs in in.readLine();. You are waiting there for the server to send another line. But the server does not. If the server would close, readLine would return with null. But the server does not close. There are several possibilities to solve this.
For the rest: you are opening and writing a complete file for every line. Better do that only once after the while loop.

Related

Messages sent from Android Server Socket is not received by applications like Packet Sender on Ubuntu or Windows

I have implemented Android ServerSocket to work with a payment device in semi integrated mode. Payment device is Android based so it will open a server socket and listens for incoming requests on a fixed port. I have also created a dummy clientApp where I send data/request to payment app and it sends the response back to cleint app. This part works.
The problem arises when I send the same request via an app like Paket Sender. In this case the request is received on server side but when I send the response back to client (Packet Sender) it does not receive anything when connection is active.
Below is my code snippet where I read the data and then send the data.
the part where I create a server socket
ServerSocket serverSocket = new ServerSocket(SERVER_PORT);
Socket socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
Then the communication thread
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
//here the clientSocket is used to listen to incoming messages from client
this.clientSocket = clientSocket;
//here this tempClientSocket is used to send messages back to client through sendMessage() methos which is defined below.
tempClientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
showMessage("Error Connecting to Client!!");
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
//we receive the incoming message in this read variable and from here we parse it and send the request to PayWorks SDK.
String read = input.readLine();
Log.e("READ"," Read->"+read);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
* Using below method we send the message back to the client. We are having problems in this part when client is an application
* like Packet Sender.
* Because we do not know how the underlying parsing of these apps works hence we cant debug it.
* What we have made sure is that result 'message' variable is
* correct here and that tempClientSocket is not null.
* But after that we just send the message over the socket and we do not have further control over it.
* This method works if client is implemented in mobile and have similar implemementation of client code as mentioned on
* android developer Socket implementation guide.
*
private void sendMessage(final String message) {
try {
Log.e("MESSAGES","Message is->"+message);
if (null != tempClientSocket) {
new Thread(new Runnable() {
#Override
public void run() {
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(tempClientSocket.getOutputStream())),
true);
} catch (IOException e) {
e.printStackTrace();
}
out.println(message);
}
}).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Can someone help me figuring out what I need to change in sendMessage() method above so that even in applications like Packet Sender I can see the data sent back by the server.
PS- I have tried most of the solutions available on SO regarding this and hence posting this as a last resort.

Problems writing to network device using sockets

I have a wireless device communicating over port 22 connected to my network. Once the device starts up, it immediately starts sending log data. Once this device is sent a command, it stops logging and responds accordingly. This all works, I have tested it using a telnet client.
My problem is that I can't seem to send it a command properly in my app. I am reading the log data as planned, but when I send it a command, in this case the command "r", it continues outputting log data instead what it should be showing me for that particular command. This has to mean that I am not properly sending the command. This is my code for the task that sends it the command and logs the output in the android logcat:
public class ReceiveVarTask extends AsyncTask<Void, Void, Void>{
String dstAddress;
int Port;
ReceiveVarTask(String addr, int port) {
dstAddress = addr;
Port = port;
}
protected Void doInBackground(Void... vars){
Socket socket = null;
String command = "r";
try {
Log.i(TAG, "Connecting to port 22");
socket = new Socket(dstAddress, Port);
Log.i(TAG, "Connected to port 22");
PrintWriter writer = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
writer.println(command);
String line = reader.readLine();
Log.i(TAG, line);
while(line!=null && !isCancelled()){
line = reader.readLine();
Log.i(TAG, line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
protected void onPostExecute(Void arg) {
taskRunning = false;
}
}
What am I doing wrong? Why is it not registering the command?
UPDATE:
I have used several telnet clients for testing, and the server is reading the 'r' command as expected on some. It works using a windows telnet client, and it works using the vSSH app by Velestar. Interestingly enough, when testing this with the android telnet client by ClockworkMod, the server is not registering the command either.
Could it be something to do with encoding?
Do I need any additional permissions to work with sockets? I have android.permission.INTERNET declared in the manifest.
UPDATE 2:
The developer of of the hardware just told me that the hardware is expecting the command to be ASCII encoded and CR terminated. So I will try changing PrintWrite initialization to:
PrintWriter writer = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream(), "ASCII")), true);
and the print command to:
writer.print(command+"\r");
Changing the the encoding type to "US-ASCII" and adding a carriage return instead of a new line did the trick. I'm able to read and write data as expected.
From my understanding of your problem description, you have a telnet server, and when a telnet client connects to that server, the server start sending the client log data. The client may send an "r" to the server to stop the log stream.
I suggest you first confirm using another telnet client that sending an "r" does stop the server from generating more log data.
You could use Wireshark to check if the "r" command is indeed sent.

Sending message from Android client to Java server

I am developing an Android application, and I need to send a message from the application to the Java Server.
Java Server works like this:
thread = new Thread(){
public void run(){
System.out.println("Server is running...");
try {
ServerSocket socket = new ServerSocket(7000);
while(true){
Socket s = socket.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("Received from client: " + dis.readUTF());
dis.close();
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
In my application I send the message in this way:
mt = new Thread() {
public void run() {
try {
Socket socket = new Socket("192.168.1.100", 7000);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(song_field.getText().toString());
dos.flush();
dos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
mt.start();
Toast.makeText(context, "Your Message is sent. Thank you!", Toast.LENGTH_SHORT).show();
I can send the message with emulator and my phone successfully, since they are connected to the same wifi connection, but if the device is not connected to the same network, message is not sent to the server. I want everybody to be able to send message to my computer server regardless of their internet connection.
How can I fix this problem?
In general you'll need to use something like Web Sockets to achieve what you're trying to do where, as would typically be the case, client/server are on different networks. There are a few different Web Socket implementations e.g. https://medium.com/square-corner-blog/web-sockets-now-shipping-in-okhttp-3-5-463a9eec82d1#.w9hrc1icw
EDIT
I initially misread question and thought you were trying to asynchronously send message from server to client (which would require something like Web Sockets). If you are just making requests from client to server then a typical solution would be to expose REST API from your server (and using something like Retrofit to make requests from client).

Android Client not able to connect to a server

I have a server running on my computer and I would like my android app to connect to it. In other words, I would like to write an Android client that establishes a TCP connection, writes something to the server and listens for responses from the server. Below is the client code:
public class Text extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
String fromServer, ToServer, filename;
BufferedReader inFromServer;
PrintWriter outToServer;
Socket clientSocket;
super.onCreate(savedInstanceState);
try
{
clientSocket = new Socket("86.36.32.251", 8000);
outToServer = new PrintWriter(clientSocket.getOutputStream(),true);
inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
filename = "profile.txt";
ToServer = Reader.readFileAsString(filename);
ToServer += "\n";
outToServer.println(ToServer);
while((fromServer = inFromServer.readLine()) != null)
{
TextView tv = new TextView(this);
tv.setText(fromServer);
setContentView(tv);
}
inFromServer.close();
}
catch(UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
However, when I run my application, the application does not establish a TCP connection to my server. I don't know what the problem might be. I have gone through the following link http://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/ which discusses the client-side of socket programming and I feel I have all the main steps in my client. Could someone please help me resolving the issue. Thanks
Please make sure you've added the internet permission.
If you did, run this on a real device.
If it still doesn't work, paste the logcat.

android socket connection, inputStream freezing on readline with socket.io or node websocket server

im using guava and weberknecht to convert an inputStream to a string and connect to a websocket [see this post]. Weberknecht threw me out, so im trying a very simple Socket-Connection to get any answer from the server. The Problem is, i can't read the inputStream. I don't know why.
NOTE:
On Iphone the Websocket-Server works. [i know "websocket /= socket" ... im just trying everything here to get ANY answer from the server]
My code:
try {
Socket sock = new Socket("62.212.88.234", 15000);
OutputStream out = sock.getOutputStream();
InputStream in = sock.getInputStream();
Log.e("SKT", "Reading input [! PROBLEM HERE !]");
String string = CharStreams.toString(new InputStreamReader(in,
"UTF-8"));
Log.e("SKT", "Answer [! NEVER REACHED !]:" + string);
sock.close();
} catch (UnknownHostException e) {
Log.e("SKT", "UnknownHostException: " + e.getMessage());
} catch (IOException e) {
Log.e("SKT", "IOException: " + e.getMessage());
}
Thanks for the Help in advance.
The documentation for CharStreams.toString says:
Reads all characters from a Readable object into a String.
My guess is that the remote end does not close the socket, so there's no end-of-stream to consume, thus the freeze.

Categories

Resources