The code is supposed to connect as a client to a TCP server, send a command and receive a response.
The code connects and sends the command but time-out-s at "socket.getInputStream()", even though the connected server receives the command and is supposed to respond (was checked using a TCP client program on the PC).
Here Is the Code for the task:
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String command;
String response = "";
MyClientTask(String addr, int port, String cmd){
dstAddress = addr;
dstPort = port;
command = cmd;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
InputStream inputStream;
try {
socket = new Socket();
socket.connect(new InetSocketAddress(dstAddress, dstPort),2000);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.println(command);
inputStream = socket.getInputStream();
socket.setSoTimeout(20000);
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
}catch (UnknownHostException e){
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
e.printStackTrace();
response = "IOException: " + e.toString();
} catch (Throwable e) {
e.printStackTrace();
response = "Throwable: " + e.toString();
}finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}//MyClientTask
You're reading the response until end of stream. End of stream won't occur until the peer closes the connection. You got a read timeout: ergo, probably, he didn't close the connection. Or else your timeout is too short. Two seconds isn't much.
You need a proper way of reading the response, or of dealing with the parts as they arrive.
Related
I am developing one Android Application in which I have to send location data on server and getting job data as a response in this way all communication is build but i am stuck of my mind on one thing when i trying to read the response from server the no any output and no any response is coming so please help me out of this stuck. Below is my code. Thanks in advance.
public static class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
String s;
String red;
String loc;
String msg;
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
InputStream is=null;
BufferedReader br=null;
public MyClientTask(String addr, int port,String msg){
dstAddress = addr;
dstPort = port;
loc=msg;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
socket = new Socket(dstAddress, dstPort);
socket.setKeepAlive(true);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
is=socket.getInputStream();
socket.setSoTimeout(60*1000);
dataInputStream = new DataInputStream(is);
Log.i("socket connect","socket OK");
dataOutputStream.writeUTF(loc);
while (dataInputStream == null)
{
////this part is not working
Log.i("DEV", "sleep "+is.available());
android.os.SystemClock.sleep(100);
}
br=new BufferedReader(new InputStreamReader(dataInputStream));
String st = null;
while(socket.isConnected()){
st = br.readLine();
}
Log.w("server response", "says Server = " + st);
Dbase db2=new Dbase(mcontext);
db2.addresponse(new info(st));
Log.w("second time server response", "says 2ndTime Server = " + st);
} catch (UnknownHostException e) {
Log.e("at exception", "at thread unknownHost " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Log.e("io exception", "at thread IO " + e.getMessage());
e.printStackTrace();
}
finally{
Log.i("on finally block", "finally");
if (dataOutputStream != null){
try {
dataOutputStream.close();
} catch (IOException e) {
Log.e("io eception", "at thread dataoutput IO " + e.getMessage());
e.printStackTrace();
}
}
if (dataInputStream != null){
try {
dataInputStream.close();
} catch (IOException e) {
Log.e("data input exception", "at thread datainput IO " + e.getMessage());
e.printStackTrace();
}
}
if (socket != null){
try {
Log.i("socket", "socket closed");
socket.close();
} catch (IOException e) {
Log.e("socket exception", "at thread finally IO " + e.getMessage());
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//displayProgressBar("Downloading...");
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
You use InputStream.available method incorrectly. This method will not try to retrieve data. Actually most implementations of this method always return 0. See Inputstream available reference.
I recommend you just remove available checks and let readLine block as needed. The same goes for BufferedReader.ready - generally this does not show that you will get any data when attempting to read so this call is also not useful.
I am running a server which writes a simple Welcome message to a new Client upon Successful connection!
Now I am sure of it that my android device connects to the server but I am unable to receive the welcome text that the server sends.
I am new to socket programming and I am looking for a unified solution to this.
I will paste my code which has a successful outputStream snippet and gets the android connected to the server. I ll leave the InputStream section black, since I need the solution for that!
private ArrayBlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer>(100);
private AtomicBoolean mStop = new AtomicBoolean(false);
private OutputStream mOutputStream = null;
private InputStream mInputStream = null;
private Socket mSocket = null;
private static Thread sNetworkThread = null;
private final Runnable mNetworkRunnable = new Runnable() {
log("starting network thread");
String encoding = "UTF-8";
String output="";
#Override
public void run() {
log("starting network thread");
try {
mSocket = new Socket(ARDUINO_IP_ADDRESS, PORT);
mOutputStream = mSocket.getOutputStream();
mInputStream = mSocket.getInputStream();
} catch (UnknownHostException e1) {
e1.printStackTrace();
mStop.set(true);
} catch (IOException e1) {
e1.printStackTrace();
mStop.set(true);
}
mQueue.clear(); // we only want new values
//Output Stream
try {
while(!mStop.get()){
int val = mQueue.take();
if(val >= 0){
log("sending value "+val);
mOutputStream.write((val+"\n").getBytes());
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
try {
mStop.set(true);
if(mOutputStream != null) mOutputStream.close();
if(mSocket != null) mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//InputStream
try
{
//Call method to read inputStream
output = readFully(mInputStream,encoding);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),"Server Message"+output, Toast.LENGTH_SHORT).show();
log("returning from network thread");
sNetworkThread = null;
}
};
Well I added two methods to achieve the inputStream by calling it from the thread. The methods are as follows.
public String readFully(InputStream inputStream, String encoding)
throws IOException {
return new String(readFully(inputStream), encoding);
}
private byte[] readFully(InputStream inputStream)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toByteArray();
}
** The Server returns a String - "Welcome New User"
Well I hv used putty in RAW mode to coonect to the server and it works fine.
StackTrace Logs:
03-02 16:46:22.790 11813-12339/com.example.bonny.myapplication D/>==< ArduinoYun >==<﹕ starting network thread
03-02 16:46:22.790 11813-12339/com.example.bonny.myapplication D/libc﹕ [NET] getaddrinfo hn 9, servname NULL, ai_family 0+
03-02 16:46:22.790 11813-12339/com.example.bonny.myapplication D/libc﹕ [NET] ht 0x31302e302e302e
03-02 16:46:22.790 11813-12339/com.example.bonny.myapplication D/libc﹕ [NET] getaddrinfo-exit SUCCESS
I need to integrate the inputStream on this thread.
P.S. OutputStream works smoothly from this code!
You need to read one line. Your present code tries to read everything until end of stream, whuch only happens when the peer closes the connection.
public String convertStreamToString(java.io.InputStream is)
{
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try
{
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null)
{
sb.append(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (br != null)
{
try
{
br.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return sb.toString();
}
Above code might help you in converting InputStream into String.
I hope this will help you.
my android application needs to communicate with a server python but at the time to receive a response, the answer does not come. These are my codes:
This is my Client:
public class MainActivity extends Activity {
private Socket socket;
private static final int SERVERPORT = 5589;
private static final String SERVER_IP = "192.168.1.131";
TextView risp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
risp = (TextView) findViewById(R.id.textView1);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.editText1);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
out.println(str);
out.flush();
// Read from sock
BufferedReader input = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = input.readLine()) != null) {
response.append(line);
}
risp.setText(risp.getText().toString() + " " + response.toString());
out.close();
input.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
And this is the Server:
import socket
import sys
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
server_address = ('192.168.1.131', 5589)
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)
# Listen for incoming connections
sock.listen(1)
while True:
# Wait for a connection
print >>sys.stderr, 'waiting for a connection'
connection, client_address = sock.accept()
try:
print >>sys.stderr, 'connection from', client_address
# Receive the data
while True:
data = connection.recv(1024)
if data.lower() != 'q':
print "<-- client: ", data
else:
print "Quit from Client"
connection.close()
break
data = raw_input("--> server: ")
if data.lower() != 'q':
connection.sendall(data)
else:
print "Quit from Server"
connection.close()
break
finally:
# Clean up the connection
print "Connection close"
connection.close()
The server receive the client message, but the client doesn't receive the server message. Why?
Thanks all in advance
EDIT: I SOLVED it this way:
public class MainActivity extends Activity {
private Socket socket;
private static final int SERVERPORT = 5589;
private static final String SERVER_IP = "192.168.1.131";
TextView risp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
risp = (TextView) findViewById(R.id.textView1);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
new ConnectionTask().execute();
}
class ConnectionTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... params) {
String responce = null;
try {
EditText et = (EditText) findViewById(R.id.editText1);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
out.println(str);
out.flush();
InputStream input = socket.getInputStream();
int lockSeconds = 10*1000;
long lockThreadCheckpoint = System.currentTimeMillis();
int availableBytes = input.available();
while(availableBytes <=0 && (System.currentTimeMillis() < lockThreadCheckpoint + lockSeconds)){
try{Thread.sleep(10);}catch(InterruptedException ie){ie.printStackTrace();}
availableBytes = input.available();
}
byte[] buffer = new byte[availableBytes];
input.read(buffer, 0, availableBytes);
responce = new String(buffer);
out.close();
input.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return responce;
}
protected void onPostExecute(String responce) {
risp.setText(responce);
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
I am trying to read data continuously using the following code:
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1){
readInpt = inputStream.toString();
byteArrayOutputStream.write(buffer, 0, bytesRead);
response = byteArrayOutputStream.toString("UTF-8");
}
textResponse.setText(readInpt);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
But for some reason, it doesn't show me any output in the textbox. any help would be appreciated.
There are at least two issues in your code.
Frist, I'm not sure the method toString() on the inputStream is going to work, because the documentation says it returns a description of the object (which would be different than the string recieved). You might be confusing this with the contents of buffer which might be what you really want.
readInpt = inputStream.toString(); // Probably wrong
Second. You're updating the User Interface from a background thread, inside doInBackground() , which is always forbidden.
textResponse.setText(readInpt); // Forbidden, move somewhere else, e.g. onPostExecute()
try {
socket = new Socket(dstAddress, dstPort);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
response = stdIn.readLine();
publishProgress(response);
Log.i("response", response);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}
catch (Exception e) {
e.printStackTrace();
}
You cannot print it on text field because the socket will listen to the server socket.If server socket does not send any response it will listen to the socket continuously until the response is received.
I am trying to sending and receiving data between two mobile phones. Right now I can send data from one device (device 1) to another (device 2), however, when I am reading data in the same device (device 1) I am getting following error:
java.net.SocketException: Socket is closed
I am using the following code to read data:
SocketServerReadThread socketServerReadThread = new SocketServerReadThread(socket);
socketServerReadThread.run();
private class SocketServerReadThread extends Thread {
private Socket mySocket;
SocketServerReadThread(Socket socket) {
mySocket = socket;
}
#Override
public void run() {
try {
inputStream = mySocket.getInputStream();
byte[] buffer = new byte[1024];
byteArrayOutputStream = new ByteArrayOutputStream(1024);
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msgRead.setText(" Response: "+response);
}
});
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
message += "Read Something wrong! " + e1.toString() + "\n";
}
}
}
I would appreciate if anyone could help me to solve the problem.
private class SocketServerReadThread extends Thread {
private Socket mySocket;
SocketServerReadThread(Socket socket) {
this.mySocket = socket;
}
BufferedReader input;
input = new BufferedReader(new InputStreamReader(
this.mySocket.getInputStream()));
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
System.out.printf("Message read is -> %s%n", read);
if (read != null) {
msgRead.setText(" Response: "+response);
}
}catch(Exception e){}}}}