Android socket connection loses after app being idle for some time - android

My application listens to a socket. The application is connected to the socket using the following method.
public void connect() {
this.connectionStatus = CONNECT_STATUS_CONNECTING;
Log.v(AppConstants.DEBUG_TAG, userId + " : Connecting to Server");
if (mThread != null && mThread.isAlive()) {
return;
}
mThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread Action Started");
String secret = createSecret();
int port = (mURI.getPort() != -1) ? mURI.getPort() : (mURI.getScheme().equals("wss") ? 443 : 80);
String path = TextUtils.isEmpty(mURI.getPath()) ? "/" : mURI.getPath();
if (!TextUtils.isEmpty(mURI.getQuery())) {
path += "?" + mURI.getQuery();
}
String originScheme = mURI.getScheme().equals("wss") ? "https" : "http";
URI origin = new URI(originScheme, "//" + mURI.getHost(), null);
SocketFactory factory = mURI.getScheme().equals("wss") ? getSSLSocketFactory() : SocketFactory.getDefault();
mSocket = factory.createSocket(mURI.getHost(), port);
PrintWriter out = new PrintWriter(mSocket.getOutputStream());
out.print("GET " + path + " HTTP/1.1\r\n");
out.print("Upgrade: websocket\r\n");
out.print("Connection: Upgrade\r\n");
out.print("Host: " + mURI.getHost() + "\r\n");
out.print("Origin: " + origin.toString() + "\r\n");
out.print("Sec-WebSocket-Key: " + secret + "\r\n");
out.print("Sec-WebSocket-Version: 13\r\n");
if (mExtraHeaders != null) {
for (NameValuePair pair : mExtraHeaders) {
out.print(String.format("%s: %s\r\n", pair.getName(), pair.getValue()));
}
}
out.print("\r\n");
out.flush();
HybiParser.HappyDataInputStream stream = new HybiParser.HappyDataInputStream(mSocket.getInputStream());
// Read HTTP response status line.
StatusLine statusLine = parseStatusLine(readLine(stream));
if (statusLine == null) {
Log.v(AppConstants.DEBUG_TAG, "Received no reply from server.");
throw new HttpException("Received no reply from server.");
} else if (statusLine.getStatusCode() != HttpStatus.SC_SWITCHING_PROTOCOLS) {
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
// Read HTTP response headers.
String line;
boolean validated = false;
while (!TextUtils.isEmpty(line = readLine(stream))) {
Header header = parseHeader(line);
if (header.getName().equals("Sec-WebSocket-Accept")) {
String expected = createSecretValidation(secret);
String actual = header.getValue().trim();
if (!expected.equals(actual)) {
Log.v(AppConstants.DEBUG_TAG, "Bad Sec-WebSocket-Accept header value.");
throw new HttpException("Bad Sec-WebSocket-Accept header value.");
}
validated = true;
}
}
if (!validated) {
Log.v(AppConstants.DEBUG_TAG, "No Sec-WebSocket-Accept header.");
throw new HttpException("No Sec-WebSocket-Accept header.");
}
onConnect();
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread should be connected by now");
// Now decode websocket frames.
mParser.start(stream);
} catch (EOFException ex) {
Log.d(AppConstants.DEBUG_TAG, "WebSocket EOF!", ex);
onDisconnect(0, "EOF");
} catch (SSLException ex) {
// Connection reset by peer
Log.d(AppConstants.DEBUG_TAG, "Websocket SSL error!", ex);
onDisconnect(0, "SSL");
} catch (Exception ex) {
onError(ex);
}
}
});
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread about to be started");
mThread.start();
}
Here the problem is when I leave the application for 15 or more idle, the connection automatically closes and app becomes unusable.What is the reason behind it and how to resolve this?

Probably, it is the server that closes the idle connection. Send Ping (or Pong) periodically to keep the connection.
BTW, I guess your code is based on a certain open-source WebSocket library. If so, note that it is not of commercial quality. It does not perform even the closing handshake on disconnect().

Related

How to fix "unexpected null receiver" in android

There is a python server in my pepper robot and it works fine on the machine. I use putty to start the server and ncat to send my command and there is no problem at all.
In my Connection fragment I need to create a channel to send an ssh command to robot to start the server and then I need to create socket to the server. Then when I send a package to connect server to the application with this command: {'command': '< SYS_CONNECT>'}
In response server should send some information about robot like name, battery level and etc. BUT i just got null from server.
There is application used to run in anroid 5.1 and some years before. Now I deceided to create new application and import some class and components from old application.
private boolean connect(){
state = ConnectionState.CONNECTION_INIT;
for( String h : hostAdresses ){
try{
host = h;
// create socket
socket = new Socket( InetAddress.getByName(host).getHostAddress(), port );
socket.setSoTimeout(defaultReadTimeout);
in = new BufferedReader( new InputStreamReader( new BufferedInputStream(socket.getInputStream()) ) );
out = socket.getOutputStream();
// try to connect
int tries = connectionMaxTries;
while(!stop && socket != null && state == ConnectionState.CONNECTION_INIT && tries > 0) {
// send connection request
DataRequestPackage p = new DataRequestPackage(
PepperCommands.SYS_CONNECT,
new String[0]);
String data = gson.toJson(p);
// wait for data
//data = in.readLine();
try {
out.write(data.getBytes());
Log.w(TAG, "Sending data =" + data);
StringBuilder sb = new StringBuilder();
while ((data = in.readLine()) != null) {
sb.append(data);
Log.d(TAG, "loop data");
}
data = sb.toString();
} catch (Exception e) {
Log.d(TAG, "error on reading data");
}
Log.w(TAG, "Receiving data = " + data);
Log.w(TAG, "in.readLine(), data = " + in.readLine());
DataResponsePackage response = gson.fromJson(data, DataResponsePackage.class);
if( response.request.command == PepperCommands.SYS_CONNECT
&& response.requestSuccessfull){
state = ConnectionState.CONNECTION_ESTABLISHED;
notifyDataRecievedListeners(response);
return true;
}
tries--;
}
}catch(UnknownHostException e){
state = ConnectionState.CONNECTION_UNKNOWN_HOST;
Log.w(TAG, "Host unknown " + host);
MainActivity.getInstance().runOnUiThread( new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.getInstance().getApplicationContext(),
R.string.net_unknown_host, Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
state = ConnectionState.CONNECTION_ESTABLISHED_FAILED;
Log.w(TAG, "IO Exception on connnection with " + host + ":" + port);
}
}
return false;
}
Tries to start remote server using ssh.
/**
* Tries to start remote server using ssh.
* #return {#code true} if server started, {#code false} otherwise.
*/
private boolean sshServerStart(){
// show message
MainActivity.getInstance().runOnUiThread( new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.getInstance().getApplicationContext(),
R.string.net_try_server_start, Toast.LENGTH_SHORT).show();
}
});
// send command
String[] vCommands = new String[]{ SSH_COMMAND_SERVER_START };
if( sendSSHCommands( vCommands ).size() > 0 ){
// wait a few seconds for server to start
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
return true;
}
return false;
}
Connecting to ssh server
/**
* Connecting to ssh server
* #return {#code true} if successful connected, {#code false} otherwise.
*/
private Session connectSSH(){
for( String host : hostAdresses ){
try {
// get user information
SharedPreferences vPreferences = MainActivity.getPreferences();
String vUser = vPreferences.getString(PREFERENCES_SSH_USER, "nao");
String vPassword = vPreferences.getString(PREFERENCES_SSH_PASSWORD, "nao");
if( mUseCustomLoginData ){
vUser = mSSHUser;
vPassword = mSSHPassword;
}
// create session
Session vSession = mSSH.getSession(vUser,
InetAddress.getByName(host).getHostAddress().toString(),
22 );
vSession.setPassword( vPassword );
// avoid asking for key auth
Properties vProperties = new Properties();
vProperties.put("StrictHostKeyChecking", "no");
vSession.setConfig(vProperties);
try{
// connect to ssh server
vSession.connect();
} catch( JSchException err ){
if( err.getMessage().contains("Auth fail") ){
// ask for custom login data
if( askForCustomLoginData() ){
vSession = connectSSH();
} else {
return null;
}
} else {
System.out.println("EXCEPTION: " + err.getMessage());
err.printStackTrace();
}
}
return vSession;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (JSchException e) {
e.printStackTrace();
}
}
return null;
}
I expect on this code response.request.command return SYS_CONNECT and response.requestSuccessfull return true on this line but I got unexpected null response
if( response.request.command == PepperCommands.SYS_CONNECT && response.requestSuccessfull){

Second connection to server socket refused in android

I have a client/server socket program for android working through Direct WIFI connection.It includes several Request and Response between client and server phone. My code works perfectly for the first time but in second time client gets "Connection refused" and server "socket closed" error message.in third time it works again and in fourth time raise that errors and ....
Could anyone help me about this issue?
this is server code:
new Thread(){
public void run(){
ServerSocket welcomeSocket = null;
try {
//Create a socket and listen to that
try {
if(welcomeSocket == null)
welcomeSocket = new ServerSocket(COMMUNICATION_PORT);
}catch(Exception qwe){
Log.d("Info", "qwe:" + qwe.getMessage());
}
int i = 0;
while (i == 0) {
try {
//Waiting for client connection
socket = welcomeSocket.accept();
}catch(Exception qwe2){
Log.d("Info", "qwe2:" + qwe2.getMessage());
}
//i++;
new Thread(){
public void run(){
try {
InputStream is;
DataInputStream dIn;
OutputStream os;
DataOutputStream dOut;
//socket.setSoTimeout(SOCKET_TIMEOUT);
log("Connection accepted");
//Create an input stream for receiving data from server
is = socket.getInputStream();
dIn = new DataInputStream(is);
//Get an output stream for sending data to server phone
os = socket.getOutputStream();
dOut = new DataOutputStream(os);
boolean done = false;
byte messageType;
String message;
int serverReplyType = 0;
String serverReply = "NOP";
while (!done) {
messageType = dIn.readByte();
message = dIn.readUTF();
Log.d("Info", "Received: " + messageType);
Log.d("Info", "Received: " + message);
switch (messageType) {
//----------------------------------------
//Comparing Job ID and Location ID of client phone and server phone
case JOB_ID_CHECK_REQ:
String[] tokens = message.split("#");
serverReplyType = JOB_ID_CHECK_RESP;
if (Integer.parseInt(tokens[0]) == currentJob.getJobId() && Integer.parseInt(tokens[1]) == currentJob.getJobLocationId()) {
serverReply = "ACCEPTED";
log("Syncing data verified");
} else {
serverReply = "ID MISMATCH";
done = true;
log("It is not possible to sync none equal Jobs.");
log("Please select same Job in both phone.");
}
break;
//----------------------------------------
//Generating JSON string including Racks data
case RACK_LIST_REQ:
log("Sending Racks' data");
serverReplyType = RACK_LIST_RESP;
serverReply = racks.size() > 0 ? (new Gson()).toJson(racks) : "NOP";
break;
//----------------------------------------
//Inserting new Racks to local Db
case NEW_RACK_FOR_INSERT:
log("Receiving new Racks' data for insert");
if (!message.equals("NOP")) {
List<Rack> diffRacks = new Gson().fromJson(message, new TypeToken<List<Rack>>() {
}.getType());
rackDataSource rds = new rackDataSource(CrossPhoneSync.this);
rds.open();
rds.crossPhoneSync_InsertDiff(diffRacks);
rds.close();
}
serverReplyType = DONE;
serverReply = "NOP";
done = true;
break;
//----------------------------------------
case DONE:
done = true;
log("Done");
break;
}
Log.d("Info", "Send: " + serverReplyType);
Log.d("Info", "Send: " + serverReply);
dOut.writeByte(serverReplyType);
dOut.writeUTF(serverReply);
dOut.flush();
}
log("Operation completed!");
} catch (Exception e) {
log("Error: " + e.getMessage());
Log.d("Info", "ServerPhoneError:" + e.getMessage());
e.printStackTrace();
} finally {
//Close stream and socket
//closeSocket(true);
Disconnect(null);
}
log("Done!");
}
}.start();
}
}catch(Exception qw){
Log.d("Info", "Eq1:" + qw.getMessage());
}finally {
try {
if (welcomeSocket != null) {
welcomeSocket.close();
}
}catch (Exception e) {
Log.d("Info", "Close_ServerSocket#: " + e.getMessage());
}
}
}
}.start();
and client code:
Socket socket2 = null;
try {
InputStream is;
DataInputStream dIn;
OutputStream os;
DataOutputStream dOut;
//Create a socket for connecting to server phone
socket2 = new Socket(host, COMMUNICATION_PORT);
//socket.setSoTimeout(SOCKET_TIMEOUT);
//Get an output stream for sending data to server phone
os = socket2.getOutputStream();
dOut = new DataOutputStream(os);
//Create an input stream for receiving data from server
is = socket2.getInputStream();
dIn = new DataInputStream(is);
//Send first message
log("Sending verification data...");
int clientMessageType = JOB_ID_CHECK_REQ;
String clientMessageToSend = currentJob.getJobId() + "#" + currentJob.getJobLocationId();
dOut.writeByte(clientMessageType);
dOut.writeUTF(clientMessageToSend);
dOut.flush();
byte messageType;
String message;
boolean done = false;
while(!done) {
messageType = dIn.readByte();
message = dIn.readUTF();
Log.d("Info", "" + messageType);
Log.d("Info", message);
switch(messageType)
{
//----------------------------------------
//Sending current Job ID and Location ID to server phone for equality checking
case JOB_ID_CHECK_RESP:
if(message.equals("ACCEPTED")){
log("Data verified");
clientMessageType = RACK_LIST_REQ;
clientMessageToSend = "NOP";
log("Requesting for other phone's Racks data");
}else{
done = true;
log("It is not possible to sync none equal Jobs.");
log("Please select same Job in both phone.");
}
break;
//----------------------------------------
//Comparing...
case RACK_LIST_RESP:
log("Comparing Racks' data of two phones");
List<Rack> serverPhoneRacks;
if(!message.equals("NOP"))
serverPhoneRacks = new Gson().fromJson(message, new TypeToken<List<Rack>>() { }.getType());
else
serverPhoneRacks = new ArrayList<>();
rackDataSource rds = new rackDataSource(CrossPhoneSync.this);
rds.open();
List<Rack> diffRacks = rds.crossPhoneSync_Compare(racks,serverPhoneRacks);
rds.close();
clientMessageType = NEW_RACK_FOR_INSERT;
clientMessageToSend = diffRacks == null ? "NOP" : (new Gson()).toJson(diffRacks);
log("Sending new Racks' data for inserting on the other phone");
break;
//----------------------------------------
case DONE:
done = true;
log("Done!");
break;
}
if(!done) {
dOut.writeByte(clientMessageType);
dOut.writeUTF(clientMessageToSend);
dOut.flush();
}
}
log("Operation completed!");
}catch (Exception e) {
log("Error:" + e.getMessage());
e.printStackTrace();
Log.d("Info", " ClientPhoneError:" + e.getMessage());
}finally {
//Close stream and socket
//closeSocket(false);
try {
if (socket2 != null) {
//socket.shutdownInput();
//socket.shutdownOutput();
socket2.close();
}
}catch (Exception e) {
Log.d("Info", "Close_Socket_Error5: " + e.getMessage());
}
}
log("Finished!");

Update android UI from do in background task

I am using AsyncTask to do a background task. The task is in a while loop.
How can I update my UI as on post execute dose not work if the background task is still running.
Thanks
protected String doInBackground(Void... params) {
while(true){
Log.i(LOG_TAG, "Executing Background Task");
try{
String dataFromBT = btc.getData();
Log.i(LOG_TAG, "BT Data: "+dataFromBT);
if(dataFromBT.contains("B1")){
dataFromBT = "Warning Message 1";
}
if(dataFromBT.contains("B2"))
{
dataFromBT="Warning Message 2";
}
if(dataFromBT.contains("B3")){
dataFromBT="Warning Message 3";
}
if(dataFromBT.contains("B4")){
dataFromBT="Warning Message 4";
}
if (groupOwnerAddress!=null) {
Log.i(LOG_TAG, "Info is not null mobiles connected");
// This is the server side
if (isthisthegrpowner == true) {
Log.w(LOG_TAG, "Group Owner: I am the Group Owner ");
Log.w(LOG_TAG, "Group Owner: Opening a Server Socket");
ServerSocket serverSocket;
serverSocket = new ServerSocket(8988);
Log.w(LOG_TAG, "Group Owner: Server Socket Opened, waiting for PEER");
Socket client = serverSocket.accept();
Log.w(LOG_TAG, "Group Owner: Server Connection Done");
serverSocket.setReuseAddress(true);
try{
// Get client IP from Socket
clientipadd = client.getRemoteSocketAddress();
clientport = client.getPort();
String clientip = clientipadd.toString();
Log.w(LOG_TAG, "Group Owner: Client IP from socket found: " + clientip);
Log.w(LOG_TAG, "Group Owner: Input Stream Started");
InputStream inputstream = client.getInputStream();
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
String response = "";
int bytesRead;
while ((bytesRead = inputstream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
// Split the string sent from the client and add it to the HashMap
String input = response;
final String[] splitStringArray = input.split(" ");
String a = splitStringArray[0];
String b = splitStringArray[1];
String c = splitStringArray[2];
String d = splitStringArray[3];
String e = splitStringArray[4];
Log.w(LOG_TAG, "Group Owner: Response from client split: " + " 1: " + a + " 2: "+ b + " 3:" + c + " 4: " + d + " 5: " + e );
data.put(clientip, new VehicleInfoEntry(a, b , c));
client.shutdownInput();
Log.w(LOG_TAG, "Group Owner: Reply from Peer: " + response);
}finally{
Log.w(LOG_TAG, "Group Owner: Output Stream started");
OutputStream stream = client.getOutputStream();
PrintStream printStream = new PrintStream(stream);
printStream.print("hello hellomac hellodata" + Latitude + " " + Longitude + dataFromBT);
Log.w(LOG_TAG, "Group Owner: Output Stream finished");
serverSocket.close();
Log.w(LOG_TAG, "Group Owner: Socket Closed");
}
// This is the client side
} else{
Log.w(LOG_TAG, "PEER: I am a PEER");
InetAddress ownerAdd = groupOwnerAddress;
int ownerPort = 8988;
Socket server = new Socket();
try {
server.connect((new InetSocketAddress(ownerAdd, ownerPort)));
Log.w(LOG_TAG, "PEER: Socket done ");
Log.w(LOG_TAG, "PEER: Output Stream Started ");
OutputStream stream = server.getOutputStream();
PrintStream printStream = new PrintStream(stream);
printStream.print("hello hellomac hellodata" + " " + Latitude + " " + Longitude + dataFromBT);
Log.w(LOG_TAG, "PEER: Output Stream Done");
server.shutdownOutput();
// printStream.close();
} finally {
Log.w(LOG_TAG, "PEER: Input Stream Started");
InputStream inputstream = server.getInputStream();
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
String response = "";
int bytesRead;
while ((bytesRead = inputstream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
Log.w(LOG_TAG, "PEER: Reply from Group Owner: " + response);
server.close();
Log.w(LOG_TAG, "PEER: Server socket closed");
}
}
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}finally {
}try {
Thread.sleep(2000); // changed to 5000 for other peer
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
If you want to use the UI from background thread then use runOnUiThread as below in doInBackground
runOnUiThread(new Runnable(){
public void run() {
// update UI
}
Use the publishProgress method. Anything you do in the onProgressUpdate, runs on the UI thread
private class TestAsyncTask extends AsyncTask<Void, String, Void> {
#Override
protected Void doInBackground(Void... voids) {
SystemClock.sleep(1000);
publishProgress("Test");
SystemClock.sleep(1000);
return null;
}
#Override
protected void onProgressUpdate(String... values) {
String test = values[0];
// Do something with it
}
}
protected void onProgressUpdate (Progress... values)
Added in API level 3 Runs on the UI thread after
publishProgress(Progress...) is invoked. The specified values are the
values passed to publishProgress(Progress...).
Parameters values The values indicating progress.

Android socket connection timeout

My android app is connected to the server through socket, which is coded in node.js. When the is left in the foreground for 15 minutes it losses connection to the server. The following is the code that connects the sockt to the server
public void connect() {
this.connectionStatus = CONNECT_STATUS_CONNECTING;
Log.v(AppConstants.DEBUG_TAG, userId + " : Connecting to Server");
if (mThread != null && mThread.isAlive()) {
return;
}
mThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread Action Started");
String secret = createSecret();
int port = (mURI.getPort() != -1) ? mURI.getPort() : (mURI.getScheme().equals("wss") ? 443 : 80);
String path = TextUtils.isEmpty(mURI.getPath()) ? "/" : mURI.getPath();
if (!TextUtils.isEmpty(mURI.getQuery())) {
path += "?" + mURI.getQuery();
}
String originScheme = mURI.getScheme().equals("wss") ? "https" : "http";
URI origin = new URI(originScheme, "//" + mURI.getHost(), null);
SocketFactory factory = mURI.getScheme().equals("wss") ? getSSLSocketFactory() : SocketFactory.getDefault();
mSocket = factory.createSocket(mURI.getHost(), port);
mSocket.setKeepAlive(true);
PrintWriter out = new PrintWriter(mSocket.getOutputStream());
out.print("GET " + path + " HTTP/1.1\r\n");
out.print("Upgrade: websocket\r\n");
out.print("Connection: Upgrade\r\n");
out.print("Host: " + mURI.getHost() + "\r\n");
out.print("Origin: " + origin.toString() + "\r\n");
out.print("Sec-WebSocket-Key: " + secret + "\r\n");
out.print("Sec-WebSocket-Version: 13\r\n");
if (mExtraHeaders != null) {
for (NameValuePair pair : mExtraHeaders) {
out.print(String.format("%s: %s\r\n", pair.getName(), pair.getValue()));
}
}
out.print("\r\n");
out.flush();
HybiParser.HappyDataInputStream stream = new HybiParser.HappyDataInputStream(mSocket.getInputStream());
// Read HTTP response status line.
StatusLine statusLine = parseStatusLine(readLine(stream));
if (statusLine == null) {
Log.v(AppConstants.DEBUG_TAG, "Received no reply from server.");
throw new HttpException("Received no reply from server.");
} else if (statusLine.getStatusCode() != HttpStatus.SC_SWITCHING_PROTOCOLS) {
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
// Read HTTP response headers.
String line;
boolean validated = false;
while (!TextUtils.isEmpty(line = readLine(stream))) {
Header header = parseHeader(line);
if (header.getName().equals("Sec-WebSocket-Accept")) {
String expected = createSecretValidation(secret);
String actual = header.getValue().trim();
if (!expected.equals(actual)) {
Log.v(AppConstants.DEBUG_TAG, "Bad Sec-WebSocket-Accept header value.");
throw new HttpException("Bad Sec-WebSocket-Accept header value.");
}
validated = true;
}
}
if (!validated) {
Log.v(AppConstants.DEBUG_TAG, "No Sec-WebSocket-Accept header.");
throw new HttpException("No Sec-WebSocket-Accept header.");
}
onConnect();
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread should be connected by now");
// Now decode websocket frames.
mParser.start(stream);
} catch (EOFException ex) {
Log.d(AppConstants.DEBUG_TAG, "WebSocket EOF!", ex);
onDisconnect(0, "EOF");
} catch (SSLException ex) {
// Connection reset by peer
Log.d(AppConstants.DEBUG_TAG, "Websocket SSL error!", ex);
onDisconnect(0, "SSL");
} catch (Exception ex) {
onError(ex);
}
}
});
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread about to be started");
mThread.start();
}
anu solution to this problem?
After googling a lot I found out a solution to this problem. Add timeout to the socket connection.
mSocket.setSoTimeout(10*1000);
If there isn't any response, after 10 seconds it will throw SocketTimeoutException and in the catch of this exception close the connection if exists, then connect again.
catch (SocketTimeoutException e) {
if (mSocket.isConnected()) {
disconnect();
}
connect();
}
This is a simple example that shows how to set the timeout on a java socket :
sockAdr = new InetSocketAddress(SERVER_HOSTNAME, SERVER_PORT);
socket = new Socket();
timeout = 5000; // 5 seconds
socket.connect(sockAdr, timeout);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream());
while ((data = reader.readLine())!=null)
log.e(TAG, "received -> " + data);
log.e(TAG, "Socket closed !");

Communicating android and windows through socket

I want to make my android app open socket to my windows console app and they communicate with each other. The socket is opened and data is sent and received in windows app, but my android app does not receive the answer which sent by windows. I watch the packets in my android and I saw the packets are coming but I do not know why my app do not receive it!
windows app server class:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
Console.WriteLine("\nStarting server...");
this.tcpListener = new TcpListener(IPAddress.Any, 1234);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
Console.WriteLine("\nWaiting for clients to connect...");
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
Console.WriteLine("\nIncoming from client...");
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
try
{
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("\nReceived: \n\n" + encoder.GetString(message, 0, bytesRead));
//By FMR
string response = "random responsive: " + new Random().Next(1000).ToString() + "\n";//"\r\n";
//writeData(clientStream, response);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response);
// Send back a response.
clientStream.Write(msg, 0, msg.Length);
clientStream.Flush();
Console.WriteLine("\nResponed ..." + response);
}
}
catch (Exception ex)
{
Console.WriteLine("\nException while: " + ex.Message);
}
tcpClient.Close();
}
}
my android thread:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Socket socket = null;
ServerSocket serverSocket = null;
Boolean bRun = true;
try {
socket = new Socket(ip, port);
if(outputStream == null) {
outputStream = new DataOutputStream(socket.getOutputStream());
}
// become server
serverSocket = new ServerSocket(port);
Log.i(G.TAG, "before serverSocket.accept");
socket = serverSocket.accept();
Log.i(G.TAG, "response recieve: ");
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (Exception e) {
try {
serverSocket.close();
} catch (IOException e1) {
Log.e(G.TAG, "serverSocket.close() e: " + e1.getMessage());
}
try {
socket.close();
} catch (IOException e1) {
Log.e(G.TAG, "socket.close() e: " + e1.getMessage());
}
}
Log.i(G.TAG, "after start recieve: ");
while (bRun) {
try {
Log.i(G.TAG, "while start: ");
String message = inputStream.readLine();
Log.i(G.TAG, "response message: " + message);
if (message != null) {
setListMessage(false, message);
}
}
catch (IOException e) {
bRun = false;
Log.e(G.TAG, "while bRun e: " + e.getMessage());
}
}
}
});
thread.start();
// in another function, my message is sent successfully from android and receive in windows
I found the problem, this line
socket = serverSocket.accept();
made the problem when I comment the line, the android app received the response!
Does anybody know why?

Categories

Resources