I'm using this code. Server and android app.
https://github.com/luugiathuy/Remote-Bluetooth-Android
I can send int commands but I want to send strings for more information
I create the issue in the repository but I want all the help posible
In the server I have this
#Override
public void run() {
try {
// prepare to receive data
InputStream inputStream = mConnection.openInputStream();
System.out.println("waiting for input");
while (true) {
int command = inputStream.read();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, Charsets.UTF_8);
String theString = writer.toString();
System.out.println(theString);
if (command == EXIT_CMD)
{
System.out.println("finish process");
break;
}
processCommand(command);
}
} catch (Exception e) {
e.printStackTrace();
}
}
with this response...
BlueCove version 2.1.1-SNAPSHOT on winsock
04c6093b00001000800000805f9b34fb
waiting for connection...
waiting for connection...
waiting for input
23456789?
finish process
BUT in Android I send "123456789" with this code
public void write(String out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out.getBytes());
}
Few edits...
I comment this line
int command = inputStream.read();
and I get the "full" string this this code
BufferedReader bReader=new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while ((line = bReader.readLine()) != null)
{
System.out.println(line);
}
123456789ÿ
I can eliminate the last char but is not the best...
In my android app I have this
mCommandService.write(editText.getText().toString().trim());
editText.getText().clear();
mCommandService.stop();
If I remove the last line, the ÿ disapear. So I guess that is the stop command. Can I remove that or is native?
Related
So, here's the situation:
I would like to use the sshj library to connect to a host which automatically runs a script on connection. Let's say the script merely logs whatever json formated input it receives. In the terminal I can run something like:
echo '{ "name" : "Hubert", "status" : "alive" }' | ssh -i ~/.ssh/id_ed25519 user#host.com
and upon connection the host would log the info { "name" : "Hubert", "status" : "alive" }.
What would an (equivalent) implementation of the above command look like in sshj?
Okay, I am not 100% sure whether all I do in the following code is entirely necessary, but it works for me:
final SSHClient ssh = new SSHClient();
/*
* Connect to host and authenticate
*/
try (Session session = ssh.startSession()){
// open a shell on host
final Shell shl = session.startShell();
// just a thread to stream stdout of host
Thread t = new Thread() {
#Override
public void run() {
try {
InputStream in = shl.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
System.out.println("## " + line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
// another thread to stream stderr of host
Thread err_t = new Thread() {
#Override
public void run() {
try {
InputStream in = shl.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
System.out.println("## " + line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
err_t.start();
// you might want to escape the input string
String input = "Some String";
byte[] data = input.getBytes();
// getOutputStream() corresponds to the hosts stdin
OutputStream out = shl.getOutputStream();
out.write(data);
// ensure all written bytes get flushed to host
out.flush();
out.close();
shl.join(5, TimeUnit.SECONDS);
shl.close();
} finally {
ssh.disconnect();
}
I have a multithreaded client-server system which works back and forth with the client communicating first and the server replying.
However, for two specific clients, I need them to constantly check if there is data held in the input stream before proceeding when the user makes an input.
The program is a car park management system. When the car park is full(0 spaces available) and a car arrives at an entrance client, the system forms a queue of clients waiting to grant entry. When a car leaves the car park, the first client in the queue is removed and added to a BlockingQueue for that specific entrance client. I have created a direct output output stream for each of the entrance clients. So when a BlockingQueue is not empty, data is taken from this queue and output is sent to the stream of that specific client.
However, the problem is - the entrance client which was queued should automatically read its InputStream and print the data to grant access, but instead it causes an error and crashes. I think what is happening is that when the system first starts, the is the client is stuck waiting to read data which initially doesn't exist because it would require some sort of input at the first stage, causing an error.
How do I fix this so that the client reads and prints the input stream(whether it be specific data such as contains the word "queue") IF there is data available else to continue IF the user makes an input.
I hope this makes sense, I tried to make it as clear as possible.
Server class:
public class Server {
public static void main(String[] args) throws IOException {
//Create the shared objects in the global scope...
int groundFloor = 0; //SET TO 0 FOR TESTING
int firstFloor = 0;
SharedState SharedStateObject = new SharedState(groundFloor,firstFloor);
//Sets up the server socket on port 4444
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(4444);
System.out.println("Car Park Server started." + "\n");
}
catch (IOException e) {
System.err.println("Could not start server on specified port.");
System.exit(-1);
}
//Got to do this in the correct order with only four clients!
ServerThread GroundFloorEntrance = new ServerThread(serverSocket.accept(), "GroundFloorEntrance", SharedStateObject);
ServerThread FirstFloorEntrance = new ServerThread(serverSocket.accept(), "FirstFloorEntrance", SharedStateObject);
ServerThread GroundFloorExit1 = new ServerThread(serverSocket.accept(), "GroundFloorExit1", SharedStateObject);
ServerThread GroundFloorExit2 = new ServerThread(serverSocket.accept(), "GroundFloorExit2", SharedStateObject);
GroundFloorEntrance.start();
FirstFloorEntrance.start();
GroundFloorExit1.start();
GroundFloorExit2.start();
serverSocket.close();
//Loop for granting queued clients access
while(true)
{
BlockingQueue<String> queuedGroundAccess = SharedStateObject.getQueuedGround();
BlockingQueue<String> queuedFirstAccess = SharedStateObject.getQueuedFirst();
if(!queuedGroundAccess.isEmpty())
{
Socket clientSocket = GroundFloorEntrance.clientSocket();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
try
{
out.println(queuedGroundAccess.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(!queuedFirstAccess.isEmpty())
{
Socket clientSocket = FirstFloorEntrance.clientSocket();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
try
{
out.println(queuedFirstAccess.take());
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
Client
public class GroundFloorEntrance {
#SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
// Set up the socket, in and out variables
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
int port = 4444;
String serverName = "localhost";
String clientID = "Ground Floor Entrance";
try {
clientSocket = new Socket(serverName, port);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + serverName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: "+ port);
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer = null;
String fromUser = null;
System.out.println("Initialised " + clientID + " client and IO connections");
//I THINK THE ISSUE IN THE FOLLOWING STRUCTURE:
while (true) {
fromServer = in.readLine();
if(fromServer != null && fromServer.contains("Queue: "))
{
System.out.println(fromServer);
}
fromUser = stdIn.readLine();
if (fromUser != null) {
out.println(fromUser);
}
fromServer = in.readLine();
System.out.println(fromServer);
}
}
}
A problem is in this loop. When you write fromServer = in.readLine(); it stop execution of your program and waits for data to be entered from server.
while (true) {
fromServer = in.readLine();
if(fromServer != null && fromServer.contains("Queue: "))
{
System.out.println(fromServer);
}
fromUser = stdIn.readLine();
if (fromUser != null) {
out.println(fromUser);
}
fromServer = in.readLine();
System.out.println(fromServer);
}
What you can do with that? You should read data from server in another thread to prevent blocking main thread while waiting for data. Like that:
new Thread(new MyRunnable(fromServer)).start();
And MyRunnable will look like this:
public class MyRunnable implements Runnable {
private Scanner scanner;
public MyRunnable(Scanner scanner) {
this.scanner = scanner;
}
#Override
public void run() {
while (true) {
if (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
}
}
If you will have some questions, please ask.
In my android app I'm creating a Socket and a BufferedReader. If i just read one line of the BufferedReader I'm getting the response from the server. But if I'm trying it with while((message = br.readLine()) != null) The application crashes. Any ideas what could be the problem?
Code
public void connecting(String uid) {
uuid = uid;
try {
client = new Socket("127.0.0.1", 8234);
try {
tv = (TextView) chat.findViewById(R.id.textView);
pw = new PrintWriter(client.getOutputStream());
br = new BufferedReader(new InputStreamReader(client.getInputStream()));
new Thread(new Runnable() {
#Override
public void run() {
try {
// If i just try this, it works
tv.append("\n"+br.readLine());
// If I'm trying this, it crashes
String message = "";
while((message = br.readLine()) != null) {
tv.append("\n"+message);
}
} catch (IOException e) {
tv.append(e.getMessage());
}
}
}).start();
tv.append("Connected!");
pw.println(uuid+":B31TR1TT");
pw.flush();
} catch (IOException e) {
tv.append(e.getMessage());
}
} catch (IOException e) {
tv.append(e.getMessage());
}
}
As algui91 said move the network calls to a separate thread. that strict mode error (violation=4) indicates network calls on ui thread.
Just refactor the network calls into a background task (service, asynctask , or whaetever ) , and the issue should go away.
Separate the UI from the business logic or network communication. Its always better and easier to test/debug.
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
Instead of while loop code try to use this code
or visit this link http://hastebin.com/inecerakes.java
Server.java:
private Socket connection;
private int ID;
public static void main(String[] args) {
int port = 19999;
int count = 0;
try{
ServerSocket socket1 = new ServerSocket(port);
System.out.println("Server Initialized");
while (true) {
Socket connection = socket1.accept();
Runnable runnable = new Server(connection, ++count);
Thread thread = new Thread(runnable);
thread.start();
}
}
catch (Exception e) {}
}
Server(Socket s, int i) {
this.connection = s;
this.ID = i;//could use a client name as it is individual id for each thread.?
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter out = new PrintWriter(connection.getOutputStream(), true);
String inputLine;
while ((inputLine = in.readLine()) != null) {
Process p = new Process();
String output = p.input(inputLine);
out.println(output);
}
}
}
catch (Exception e) {
System.out.println(e);
}
finally {
try {
connection.close();
}
catch (IOException e){}
}
}
}
When run it creates a server, which when connected to by a client creates a thread for it so that it can handle multiple clients at one time.
However the code:
while ((inputLine = in.readLine()) != null) {
Process p = new Process();
String output = p.input(inputLine);
out.println(output);
}
loops the BufferedReader to get all the input given from the client. and when receives processes it and then sends the reply back to the client to be printed.
how can i get it so that i can send/get another question via the client at the same time as the first?
e.g
"user: hello computer how are you?"
"computer:I am good, how are you?"
"user: i am good"
"computer: that is nice to hear"
works fine. but:
"user: was is 1+1?"
"computer: 1+1=2"
"computer: any more question?"
"user: good?"
does not.
how can do it so that the server give multiple answers rather than having to wait for another input?
It would be easy to do if i set output as a string in server.java however every time i try to access the string to change it
(by using
Server s = new Server(); s.output = "stuff";) as the code suggests it just makes a new thread server. how can i access the already made thread?
You have to store the client thread into a kind of map and if you need to send a message to another thread, you could look up the map and get the reference to the other thread and send message from there.
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.