I am executing shell commands from my Android APP. I am able to execute the command but unable to read the response from Server.
My code is as follows :
public String executeThroughSocket(int portNo, String portAddress, String command) throws IOException {
StringBuilder responseString = new StringBuilder();
PrintWriter writer = null;
BufferedReader bufferedReader = null;
Socket clientSocket = null;
try {
clientSocket = new Socket(portAddress, portNo);
if (!clientSocket.isConnected())
throw new SocketException("Could not connect to Socket");
clientSocket.setKeepAlive(true);
writer = new PrintWriter(clientSocket.getOutputStream(), true);
writer.println(command);
writer.flush();
bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String str;
while ((str = bufferedReader.readLine()) != null) {
responseString.append(str);
}
} finally {
if (writer != null)
writer.close();
if (bufferedReader != null)
bufferedReader.close();
if (clientSocket != null)
clientSocket.close();
}
return responseString.toString();
}
There is nothing wrong with my code. It was the server that was not sending any response.
You have to set timeout for socket
clientSocket .setSoTimeout(5000); // milisekundy
Related
I have made a socket in Java.
This socket connects with a server.
When I start my program, the server sends a message that my socket is connected with the AEOS.
When I try to login to the server for sending some commands, then the server responds again with: status connected to AEOS version
This is not the message that I expect, normally my server must send a "response true".
Can you help me?
Thanks.
import java.io.*;
import java.net.*;
class TCPClient {
public static void main(String argv[]) throws Exception {
while(true) {
String sentence;
String modifiedSentence;
Socket clientSocket = new Socket("127.0.0.1", 1201);
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
}
}
output socket
Why don't you try to read everything that server had sent? Also, need to open a new Socket every-time? Depends on your implementation. Try this:
public static void main(String[] args) {
Socket clientSocket = null;
try {
clientSocket = new Socket("127.0.0.1", 1201);
BufferedReader inFromUser = new BufferedReader(
new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String initialMessageFromServer = null;
while ((initialMessageFromServer = inFromServer
.readLine()) != null) {
System.out.println(initialMessageFromServer);
}
while (true) {
String sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
StringBuilder modifiedSentence = new StringBuilder();
String responseFromServer = null;
while ((responseFromServer = inFromServer.readLine()) != null) {
modifiedSentence.append(responseFromServer);
modifiedSentence.append('\n');
}
System.out
.println("FROM SERVER: " + modifiedSentence.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (clientSocket != null) {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I am currently starting a Thread on my device to communicate with my server.
The problem is that the code statement after the socket init is never called:
#Override
public void run(){
try{
socket = new Socket(context.getString(R.string.host), context.getResources().getInteger(R.integer.port));
Log.d("AppTest", "ActivityStart");
out = new PrintWriter(socket.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
if(socket != null){
if(awaitingString != null){
out.println(awaitingString);
out.flush();
awaitingString = null;//Reset awaiting string
}
String line;
while((line = reader.readLine()) != null){
if(line != null){
answer = line;//Overwrite answer
}
}
}else{
socket = new Socket(context.getString(R.string.host), R.integer.port);
out = new PrintWriter(socket.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
}
}catch(Exception e){
e.printStackTrace();
}
}
In the debug I should be able to AppTest: ActivityStart, but it's not showing up.
PS: I am using the IPv4 address of my computer as host
I'm trying to add a client socket in the file ViewRootImpl.java. I'm creating the socket in a new thread with an handler because I need to comunicate between threads. I'm sending a message to Vthread every time performTraversal is called.
Client code in ViewRootImpl.java:
public class Vthread extends Thread{
Viewhandler mViewhandler;
Handler mhandler;
Socket client;
BufferedReader in;
PrintWriter out;
String s;
String line;
Vthread(Viewhandler handler){
mViewhandler = handler;
in = null;
out = null;
s = "hello";
client = null;
}
#Override
public void run(){
Looper.prepare();
try{
client = new Socket("10.0.2.2", 60000);
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
}catch(IOException e){
e.printStackTrace();
}
mhandler = new Handler(){
#Override
public void handleMessage(Message msg) {
try{
if(out != null && in != null && client != null){
out.println(s);
out.flush();
line = in.readLine();
}
}catch (IOException e) {
e.printStackTrace();
}
}};
Looper.loop();
}
}
The server code in the host:
Socket socket;
ServerSocket server;
SocketAddress sockaddr;
BufferedReader in = null;
PrintWriter out = null;
String line;
String s = "bye";
server = null;
try{
sockaddr = new InetSocketAddress("127.0.0.1", 60000);
server = new ServerSocket();
server.bind(sockaddr);
socket = server.accept();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
}catch (IOException e) {
e.printStackTrace();
}
try{
System.out.println("connected");
while(!Thread.currentThread().isInterrupted()){
line = in.readLine();
System.out.println(line);
out.println(s);
}
if (server != null ) server.close();
}catch (IOException e) {
e.printStackTrace();
}
The connection is accepted but the server doesn't receive any message from client. A problem that I identified is that more than one process might be using the socket. So I used a file in the internal storage of my application to restric the socket to my application only, but the problem remains. Code to restrict the socket to my application:
if(mVthread.mhandler != null) {
try{
if(reader == null) reader = new BufferedReader(new FileReader(file));
Message msg = Message.obtain();
msg.arg1 = 1000;
mVthread.mhandler.sendMessage(msg);
}catch(Exception e){
e.printStackTrace();
}
}
EDIT
The problem is that the client socket sends a message but the server doesn't receive it. Both sides are blocked in the receive function. Any idea on what I am doing wrong?
I'm delving into sockets for the first time.
The point of the project is for the client to be able to get access to a contact list (CSV) in the server by writing "getall" and exit the program through just that command ("Exit").
The problem is that the client can only write the command and receive the list once and then the server doesn't respond to the client's input anymore.
Here is the socket code for the server and client respectively:
Server:
public class CatalogueServer extends CatalogueLoader {
ServerSocket serverSocket;
ArrayList<CatalogueEntry> catalogue;
public void startServer(int port, String catalogueFile) {
catalogue = loadLocalCatalogue(catalogueFile);
try {
serverSocket = new ServerSocket(port);
while (true) {
Socket clientSocket = serverSocket.accept();
new Thread(
new Runnable() {
public void run() {
try {
InputStream inputStream = clientSocket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader BR = new BufferedReader(inputStreamReader);
OutputStream outputStream = clientSocket.getOutputStream();
PrintWriter PW = new PrintWriter(outputStream);
String clientInput;
while ((clientInput = BR.readLine()) != null) {
System.out.println(clientInput);
if (clientInput.equals("getall")) {
System.out.println(printCatalogue(catalogue));
PW.println(printCatalogue(catalogue));
PW.flush();
break;
} else if (clientInput.equals("exit")) {
clientSocket.close();
BR.close();
PW.close();
break;
} else {
PW.flush();
break;
}
}
PW.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
).start();
}
} catch (Exception i) {
i.printStackTrace();
}
}
}
Client:
public class TestClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 5253);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader BR = new BufferedReader(inputStreamReader);
while (true) {
String clientInput;
String serverFeedback;
PrintWriter PW = new PrintWriter(outputStream);
Scanner inputScan = new Scanner(System.in, "UTF-8");
clientInput = inputScan.nextLine();
PW.println(clientInput);
PW.flush();
while ((serverFeedback = BR.readLine()) != null) {
System.out.println(serverFeedback);
}
if (clientInput.equals("exit")) {
PW.close();
socket.close();
break;
}
PW.close();
}
}
catch (IOException e){
e.printStackTrace();
}
}
}
I have tried alternating the position and renewal of the readers and writers. But I'm uncertain of where exactly the problem starts.
When you do
while ((serverFeedback = BR.readLine()) != null) {
System.out.println(serverFeedback);
}
You are reading until you reach the end of the stream, i.e. until there is nothing left. As such there is nothing after this.
If you want to reuse the connection, you have to write the code which doesn't use this pattern and only reads until it should stop reading.
I have 2 programs: a client and a server.
The server creates a ServerSocket and the client connects using:
address = InetAddress.getByName(host);
conn = new Socket(address, port);
this works, but here is the problem: void mousePressed() { gets called once the mouse is clicked, executing this: (client side)
void mousePressed() {
try {
BufferedOutputStream os = new BufferedOutputStream(conn.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII");
osw.write("123");
osw.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
the server should receive the input using:
BufferedReader reader = new BufferedReader(
new InputStreamReader(new BufferedInputStream(conn.getInputStream())));
StringBuilder result = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
result.append(line);
}
reader.close();
println(result.toString());
The server only receives the input after the socket has been closed with: conn.close(); on the client side or quitting the client. As i want to be able to click the mouse multiple times, i can't close the socket.
What can i do to send input without closing the socket?
Edit: connection code:
Server:
// init
ServerSocket socket1;
int main_port = 5204;
// in main
try {
socket1 = new ServerSocket(main_port);
Socket conn = socket1.accept();
} catch (Exception e) {
e.printStackTrace();
}
Client:
// init
String host = "localhost";
int port = 5204;
Socket conn;
InetAddress address;
// in main
try {
address = InetAddress.getByName(host);
conn = new Socket(address, port);
} catch (Exception e) {
e.printStackTrace();
}
My solution (based on other answers and comments):
1) Changing osw.write("123"); to osw.write("123\n"); in the client.
2) Replacing
BufferedReader reader = new BufferedReader(new InputStreamReader(new
BufferedInputStream(thread_cnn.getInputStream())));
StringBuilder result = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
result.append(line);
}
println(result);
reader.close();
with
BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(conn.getInputStream())));
String result = reader.readLine().toString();
println(result);
reader = null;
result = null;
on the server.
You are writing an incomplete line, and trying to read complete lines. Terminate the text you send with a line break so it can be read when it arrives.
Also, do not catch and ignore exceptions. If something goes wrong you will want to know about it.
try {
BufferedOutputStream os = new BufferedOutputStream(conn.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII");
osw.write("123\n");
osw.flush();
} catch (Exception e) {
e.printStackTrace();
}