Trying To let an android device get data from a server I have:
RetreiveFeedTask DoStuff=new RetreiveFeedTask();
try{
Work=(DoStuff.execute(Exec)).get();
}
catch(Exception e)
{System.out.print(e+"");}
Async Implementation:
class RetreiveFeedTask extends AsyncTask<String , Void , String> {
//private Exception e;
String GotBack="empty";
#Override
protected String doInBackground(String... params) {
try{
Socket socket = new Socket("192.168.1.66", 2727);
OutputStream out = socket.getOutputStream();
PrintWriter output = new PrintWriter(out);
BufferedReader input=new BufferedReader(new InputStreamReader(socket.getInputStream()));
output.println(params[0]);
output.flush();
output.close();
GotBack="OverWritten";
GotBack=input.readLine();
socket.close();
}
catch(Exception e){System.out.print(e+"");}
return GotBack;
}
}
My server is sending the ACK:
"1\n"
But what I get on the screen is "Overwritten" which is the value before I read data from the server.
Any idea why?
Update
I was closing the output socket so it was throwing an exception. Now Im not getting errors but the value I get is empty. Any idea why?
New Code:
class RetreiveFeedTask extends AsyncTask<String , Void , String> {
//private Exception e;
String GotBack="empty";
#Override
protected String doInBackground(String... params) {
try{
Socket socket = new Socket("192.168.1.66", 2727);
OutputStream out = socket.getOutputStream();
PrintWriter output = new PrintWriter(out);
BufferedReader input=new BufferedReader(new InputStreamReader(socket.getInputStream()));
output.println(params[0]);
output.flush();
String read="";
while((read=input.readLine())!=null)
{
GotBack+=read;
}
output.close();
socket.close();
}
catch(Exception e){Log.e("MyApp","exception",e);}
return GotBack;
}
}
Yes. Executing input.readLine(); must have thrown an exception which you handled and printed. The value of GotBack is now "OverWritten" which is returned on return GotBack;.
Related
I'm trying to send a string to a server over TCP using socket and AsyncTask.
String will change with the ON/OFF status of the button.
I have no error but data wont go out and I get no answer from the server.
Could someone help me to understand what I'm doing wrong ?
Part of MyActivity code (interesting section comes after //Create an instance of AsyncTask):
final MySerDeser msg = new MySerDeser();
switch (tab_ID) {
case 1:
rootView = inflater.inflate(R.layout.fragment_tab1, container, false);
//----- btn_BotolaUp
final ToggleButton btn_BotolaUp = (ToggleButton) rootView.findViewById(R.id.btn_BotolaSu);
btn_BotolaUp.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
String toastmessage;
if (isChecked) {
msg.serialize("datafield1", "datafield2", "datafield3", "1");
toastmessage = "Chiusura botola start";
} else {
msg.serialize("datafield1", "datafield2", "datafield3", "0");
toastmessage = "Chiusura botola stop";
}
//Create an instance of AsyncTask
ClientAsyncTask clientAST = new ClientAsyncTask();
Log.d("NetStuff" , "ClientAsyncTask");
//Pass the server ip, port and client message to the AsyncTask
clientAST.execute(new String[] { "192.168.1.100", "10000",msg.serialized });
Log.d("NetStuff", "clientAST.execute(new String[]...");
Toast.makeText(rootView.getContext(), toastmessage, Toast.LENGTH_SHORT).show();
}
});
The AsyncTask code:
/**
* AsyncTask which handles the communication with the server
*/
class ClientAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String result = null;
Log.d("NetStuff" , "String doInBackground");
try {
//Create a client socket and define internet address and the port of the server
Socket socket = new Socket(params[0],
Integer.parseInt(params[1]));
Log.d("NetStuff" , "Socket socket = new Socket");
//Get the input stream of the client socket
InputStream is = socket.getInputStream();
Log.d("NetStuff" , "InputStream is = socket.getInputStream");
//Get the output stream of the client socket
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
Log.d("NetStuff" , "PrintWriter out = new PrintWriter");
//Write data to the output stream of the client socket
out.print(params[2]);
Log.d("NetStuff", "out.print(" + params[2] + ")");
//Buffer the data coming from the input stream
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
Log.d("NetStuff" , "BufferedReader br = new BufferedReader");
//Read data in the input buffer
result = br.readLine();
Log.d("NetStuff" , "result = br.readLine()");
//Close the client socket
socket.close();
Log.d("NetStuff", "socket.close");
} catch (NumberFormatException e) {
Log.d("NetStuff", "NumberFormatException");
e.printStackTrace();
} catch (UnknownHostException e) {
Log.d("NetStuff", "UnknownHostException");
e.printStackTrace();
} catch (IOException e) {
Log.d("NetStuff", "IOException");
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String s) {
//Write server message to the text view
Log.d("NetStuff","Server answer:" + s);
}
}
Logcat is the following:
01-06 08:58:32.743 31685-31685/com.dev.netmanagement D/NetStuff: ClientAsyncTask
01-06 08:58:32.743 31685-31685/com.dev.netmanagement D/NetStuff: clientAST.execute(new String[]...
01-06 08:58:32.743 31685-31742/com.dev.netmanagement D/NetStuff: String doInBackground
01-06 08:58:32.753 31685-31742/com.dev.netmanagement D/NetStuff: Socket socket = new Socket
01-06 08:58:32.753 31685-31742/com.dev.netmanagement D/NetStuff: InputStream is = socket.getInputStream
01-06 08:58:32.763 31685-31742/com.dev.netmanagement D/NetStuff: PrintWriter out = new PrintWriter
01-06 08:58:32.773 31685-31742/com.dev.netmanagement D/NetStuff: out.print(datafield1,datafield2,datafield3,1)
01-06 08:58:32.773 31685-31742/com.dev.netmanagement D/NetStuff: BufferedReader br = new BufferedReader
Looking with wireshark, I see that no data are going out..
Looking # logcat, it's clear that task is waiting an answer from the server.
The answer will never arrive because the server has no question to answer...
Commenting following code:
//Buffer the data coming from the input stream
/*BufferedReader br = new BufferedReader(
new InputStreamReader(is));
Log.d("NetStuff" , "BufferedReader br = new BufferedReader");
//Read data in the input buffer
result = br.readLine();
Log.d("NetStuff" , "result = br.readLine()");
*/
//Close the client socket
socket.close();
Log.d("NetStuff", "socket.close");
The task end and socket is closed (but still no one TCP string out from the ethernet).
Why my awful code is not transmitting ? [Help]
[SOLVED]
Thanks to greenapps, I add out.flush() and all is now working.
So, if you need to send TCP data declare following class:
/**
* AsyncTask which handles the communication with the server
*/
class ClientAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String result = null;
try {
//Create a client socket and define internet address and the port of the server
Socket socket = new Socket(params[0],
Integer.parseInt(params[1]));
//Get the input stream of the client socket
InputStream is = socket.getInputStream();
//Get the output stream of the client socket
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
//Write data to the output stream of the client socket
out.print(params[2]);
out.flush();
//Buffer the data coming from the input stream
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
//Read data in the input buffer
result = br.readLine();
//Close the client socket
socket.close();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String s) {
//Write server message to the text view
Log.d("NetStuff","Server answer:" + s);
}
}
And call task with:
//Create an instance of AsyncTask
ClientAsyncTask clientAST = new ClientAsyncTask();
//Pass the server ip, port and client message to the AsyncTask
clientAST.execute(new String[]{"192.168.1.100", "10000", "message to send"});
Great !
So first of all I'm trying to do a Client Socket and ASync Task program using android.
It builds and installs successfully, but when I open the application, it crashes and logcat says that
"E/AndroidRuntime( 271): FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime( 271): java.lang.RuntimeException: An error occured while executing doInBackground()"
public class AsyTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... ad) {
Socket socket = null;
OutputStream os = null;
StringBuffer output = null;
try {
socket = new Socket(ad[0], Integer.parseInt(ad[1]));
} catch (java.lang.Exception e) {
e.printStackTrace();
}
try {
os = socket.getOutputStream();
os.write("GET / \r\n".getBytes());
os.flush();
output = new StringBuffer("");
InputStream is = socket.getInputStream();
BufferedReader bufReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(is)));
String line = "";
while ((line = bufReader.readLine()) != null) {
output.append(line);
output.append("\n");
}
bufReader.close();
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
protected void onPostExecute(String result) {
System.out.println(result);
}
}
I am programming a small ChatServer program, and I've nailed down the error to this part of the client code
public void run() {
Client client = new Client();
try {
Socket s = new Socket("localhost", 25555);
client.os = new DataOutputStream(s.getOutputStream());
InputStreamReader isr = new InputStreamReader(s.getInputStream());
BufferedReader br = new BufferedReader(isr);
while (!exit){
String str = Input.read_string();
client.os.writeUTF(ID+"=CLID"+str.toLowerCase());
client.os.flush();
System.out.println(br.readLine());
}
} catch ( IOException e) {
e.printStackTrace();
}
}
The Input.read_string() code is the following:
class Input{
public static String read_string() {
String read="";
try {
read = new BufferedReader(new InputStreamReader(System.in), 1).readLine();
} catch (IOException ex) {
System.out.println("error reading from the input stream!");
}
return read;
}
}
When I put the System.out.println(br.readLine()); at the beginning of the while loop the first time another client chats, but after that one has to input to get the next update.
Also, this may be fixed with the last error, but when it does update, it is the last thing the other client sent.
The code works fine when I close the client just after sending one instruction. But when I want a client and server connection to persist, so that the client can send multiple instructions to the server one after another, I get a Null pointer exception at the server and the message java.net.SocketException: Socket is closed at the client. This happens after the client sends a file to the server and the server successfully receives it. Need help. The error occurs at the Connection class code line switch(clientMsg). It seems to me that for some reason the BufferedReader in goes null, but I might be mistaken about that. The code is as follows. Thanks.
Server
public class server {
private static ServerSocket serverSocket;
private static Socket socket = null;
public static void print(Object s) {
System.out.println(s);
}
#SuppressWarnings("resource")
public static void main (String args[]) throws IOException {
System.out.print("Specify listening port: ");
Scanner _a = new Scanner(System.in);
int a = _a.nextInt();
try{
serverSocket = new ServerSocket(a);
}
catch(IOException e) {
System.out.println(e);
}
while (true) {
try {
socket = serverSocket.accept();
print("Connected to " + socket);
Thread client = new Thread(new Connection(socket));
client.start();
}
catch (IOException e) {
print(e);
}
}
}
}
Connection
public class Connection implements Runnable {
public static void print(Object s) {
System.out.println(s);
}
private Socket socket;
private BufferedReader in = null;
public Connection(Socket client) {
this.socket = client;
}
#Override
public void run(){
try {
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String clientMsg;
while (true) {
clientMsg = in.readLine();
switch (clientMsg) {
case "1":
receiveFile(); //method code not included
break;
default:
print("Command not recognized");
break;
}
//in.close();
}
}//try run()
catch (IOException e) {
print(e);
}
}
Client
public class client {
private static Socket connectToServer;
private static String fileName;
private static BufferedReader keybrdIn;
private static PrintStream msgToServer;
public static void println(Object e) {
System.out.println(e);
}
public static void print(Object e) {
System.out.print(e);
}
public static void main(String args[]) throws IOException{
try{
print("Enter IP: ");
String ip = new Scanner(System.in).nextLine();
print("Enter port: ");
int port = new Scanner(System.in).nextInt();
connectToServer = new Socket(ip, port);
keybrdIn = new BufferedReader(new InputStreamReader(System.in));
}catch(IOException e) {
println(e);
}
msgToServer = new PrintStream(connectToServer.getOutputStream());
while (true) {
try {
switch(Integer.parseInt(action())) { //action() method code not included
case 1:
msgToServer.println("1");
sendFile();
break;
default:
println("Invalid input");
break;
}
}catch (IOException e) {
println(e);
}
}
}
sendFile()
public static void sendFile() throws IOException {
print("Enter file name: ");
fileName = keybrdIn.readLine();
File file = new File(fileName);
byte[] bytearray = new byte[8192];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os = connectToServer.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(file.getName());
int count;
while ((count = dis.read(bytearray)) > 0){
dos.write(bytearray, 0, count);
}
dis.close();
dos.flush();
dos.close();
}
receiveFile()
public void receiveFile() {
try {
int count;
DataInputStream clientFileStream = new DataInputStream(socket.getInputStream());
String fileName = clientFileStream.readUTF();
OutputStream fileOutput = new FileOutputStream("_" + fileName);
byte[] mybytearray = new byte[8192];
BufferedOutputStream bos = new BufferedOutputStream(fileOutput);
System.out.println("Downloading " + fileName + " ...");
//outToClient().writeBytes("Uploading. Please wait...\n");
while ((count = clientFileStream.read(mybytearray)) > 0){
bos.write(mybytearray, 0, count);
}
fileOutput.close();
bos.close();
clientFileStream.close();
}
catch (IOException e) {
print(e);
}
}
In sendFile(), you close the data output stream which closes your underlying connection's output stream.
According to the documentation of Socket.getOutputStream():
"Closing the returned OutputStream will close the associated socket".
Since you already closed stream, it will also close socket as well as Eyal mentioned. However, at the moment you close the stream, server side will aware of that and return -1 for read() results.
So, even if you didn't specify file length at beginning, this will generally works well.
However, since you already closed stream, you can't reuse it no matter what. To fix this issue, probably you need to change your Client class so that Client should create socket connection, send files, close socket. That's one lifecycle of opened client socket.
Or maybe in while loop of Client class, 1) take ip, port, and filename to send 2) Create new Thread and provide those information so let thread open connection, send file, close connection 3) and in the meantime, client while() can keep take next ip, port, and filename to send from the user. By doing this, you don't need to make client program wait until file transfer to be completed.
Regarding the NPE in the server, readLine() returns null at end of stream. You are ignoring it. You should be testing for it immediately after the call, and if null close the socket and exit the read loop.
I am trying to create simple app with android client and java server
android client is able to send message to server(java)
while when i try to read server reply
error:socket closed.
line(if((receiveMessage = receiveRead.readLine()) != null) )
public class ClientConnectorTask extends AsyncTask<String, Void, Integer> {
private Socket client;
private PrintWriter printwriter;
protected Integer doInBackground(String...strings) {
// validate input parameters
if (strings.length <= 0) {
return 0;
}
// connect to the server and send the message
try {
client = new Socket("192.168.1.4", 7777);
printwriter = new PrintWriter(client.getOutputStream(),true);
//while(true){
InputStream istream = client.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
String receiveMessage;
while (true){
// printwriter.write(strings[0]);
printwriter.print(strings[0]);
printwriter.flush();
printwriter.close();
if((receiveMessage = receiveRead.readLine()) != null) //receive from server
{
System.out.println(receiveMessage); // displaying at DOS prompt
}
}
//}
//client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
protected void onPostExecute(Long result) {
return;
}
}
Closing the PrintWriter inside the loop doesn't make sense, and closing it before the readLine() call doesn't make sense either. Closing either the input or the output stream of a Socket closes the other stream and the socket.