I should insert a timeout on a readLine for a bluetooth input stream.
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter()
.getRemoteDevice("00:00:00:00:00:00");
sock = device.createInsecureRfcommSocketToServiceRecord(UUID
.fromString(insecureUUID));
sock.connect();
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String line = in.readLine(); //if no answer from device..i'll wait here forever
do { [...]
} while ((line = in.readLine()) != null);
The connection works fine, but i've got a bluetooth serial converter linked to another device. If the second one is turned off i'll wait forever on the readLine. Any chance i can throw an exception or a timeout?
Thanks!!
I had the same problem and i solved it by creating a ResponderThread that extends Thread. This thread waits a certain amount of time and after that it checks if the input stream variable have changed.
try {
bufferedReader = new BufferedReader(new InputStreamReader(
bluetoothSocket.getInputStream()));
responderThread = new ResponderThread(bluetoothSocket, ACCESS_RESPONSE);
responderThread.start();
response= bufferedReader.read();
} catch (IOException ioe) {
// Handle the exception.
}
In my case the responderThread closes the socket if there is no response within 3 seconds and the execution goes into the catch block of the class where i create the responderThread. Then the exception is handled.
Related
I'm trying to send some commands to Android (client) from VB.NET (server) using sockets. I can connect the client to the server, but I don't know how to receive the commands sent by the server.
Here's a part of my Android code:
public void connect(View v){ //called on button click
SERVER_IP = ip.getText().toString(); //it gets the server's ip from an editText
SERVER_PORT = Integer.parseInt(port.getText().toString()); //and the port too
Toast.makeText(this, "Trying to connect to\n" + SERVER_IP + ":" + SERVER_PORT + "...", Toast.LENGTH_SHORT).show();
new Thread(new Runnable() {
public void run() {
InetAddress serverAddr;
try {
serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVER_PORT); //It establishes the connection with the server
if(socket != null && socket.isConnected()){ //not sure if it is correct
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//Here comes the problem, I don't know what to add...
}
} catch (Exception e) {
}
}
}).start();
}
And here's a part of my VB.NET send code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
send(TextBox1.text)
End Sub
Private Sub Send(ByVal command)
Dim temp() As Byte = UTF8.GetBytes(command) 'Is UTF8 right to use for that?
stream.Write(temp, 0, temp.Length)
stream.Flush()
End Sub
Question1: is it right to us UTF8 instead of for example ASCII encoding?
Question2: what would I change in the Android code if it wanted to use a timer that sends a command every second?
Thanks.
To read input from a BufferedReader you need to do something similiar to this:
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while((line = input.readLine()) != null){
// do something with the input here
}
A nice tutorial on sockets is available from oracle in the docs: http://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
The default charset on Android is UTF-8 http://developer.android.com/reference/java/nio/charset/Charset.html, so no worries there but you can always send a byte stream from the server onto the client and decode it however you want.
To receive a byte stream you need to do this:
BufferedInputStream input = new BufferedInputStream(socket.getInputStream());
byte[] buffer = new byte[byteCount];
while(input.read(buffer, 0, byteCount) != -1 ){
// do something with the bytes
// for example decode it to string
String decoded = new String(buffer, Charset.forName("UTF-8"));
// keep in mind this string might not be a complete command it's just a decoded byteCount number of bytes
}
As you see it's much easier if you send strings instead of bytes.
If you want to receive input from the server periodically, one of the solutions would be to create a loop which opens a socket, receives input, process it, closes the socket, and then repeats, our you could just keep the loop running endlessly until some command like "STOP" is received.
I am trying to receive port based SMS with the below piece of code.
serverSocket = new ServerSocket(SERVERPORT);
Socket client = serverSocket.accept();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
line = null;
while ((line = in.readLine()) != null) {
Log.d("ServerActivity", line);
System.out.println("Reading Line is>>>>>>>>>>>>>"+line);
break;
}
} catch (Exception e) {
System.out.println("Exception While Reading SMS>>>>>>>>>>"+e);
}
Will it wait in the line of serverSocket.accept(); until it gets the port based SMS,Is this correct behaviour or I am making any issue which hangs at that place.I am not able to move beyond it.
I am not able to test fully,I am not having option of testing it here,sending the port message.
Did anyone came across this issue.Any Info regarding this will be useful.
I think you could try adding the while statement
serverSocket = new ServerSocket(SERVERPORT);
while(true){
Socket client = serverSocket.accept();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
line = null;
while ((line = in.readLine()) != null) {
Log.d("ServerActivity", line);
System.out.println("Reading Line is>>>>>>>>>>>>>"+line);
break;
}
} catch (Exception e) {
System.out.println("Exception While Reading SMS>>>>>>>>>>"+e);
}
}
and for as long as it's true, it will wait for the client to send a message. It's been a while since i last did one of these Working with Datagrams
The first time I made a method to read data from my chat server, it frooz. I found out I had the wrong port number and it was freezing at
new BufferedReader(new InputStreamReader(conn.getInputStream()));
Is there a way to have a time out so my program does not freez on a network error? I'm assuming there must be,
the complete methed
void SendMessage()
{
try {
URL url = new URL("http://50.63.66.138:1044/update");
System.out.println("make connection");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// String line;
String f=new String("");
String line=new String();
while ((line= rd.readLine() ) != null) {
f=f+line;
f+="\n";
}
mUsers.setText(f);
} catch (Exception e) {
System.out.println("exception");
System.out.println(e.getMessage());
}
}
}
First of all, I hope you execute this code in a separate thread in order to make your UI thread responsive on touches even while connection is being established.
Second, there are two timeout methods available for URLConnection class:
http://developer.android.com/reference/java/net/URLConnection.html#setReadTimeout(int)
http://developer.android.com/reference/java/net/URLConnection.html#setConnectTimeout(int)
Try to play with these guys, maybe it will help.
If not, you can always do your own way:
start the thread with a runnable which tries to establish a connection and InputReader. Then wait for some time-out and try to interrupt the thread if it is still running.
The following code basically works as expected. However, to be paranoid, I was wondering, to avoid resource leakage,
Do I need to call HttpURLConnection.disconnect, after finish its usage?
Do I need to call InputStream.close?
Do I need to call InputStreamReader.close?
Do I need to have the following 2 line of code : httpUrlConnection.setDoInput(true) and httpUrlConnection.setDoOutput(false), just after the construction of httpUrlConnection?
The reason I ask so, is most of the examples I saw do not do such cleanup. http://www.exampledepot.com/egs/java.net/post.html and http://www.vogella.com/articles/AndroidNetworking/article.html. I just want to make sure those examples are correct as well.
public static String getResponseBodyAsString(String request) {
BufferedReader bufferedReader = null;
try {
URL url = new URL(request);
HttpURLConnection httpUrlConnection = (HttpURLConnection)url.openConnection();
InputStream inputStream = httpUrlConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
int charRead = 0;
char[] buffer = new char[1024];
StringBuffer stringBuffer = new StringBuffer();
while ((charRead = bufferedReader.read(buffer)) > 0) {
stringBuffer.append(buffer, 0, charRead);
}
return stringBuffer.toString();
} catch (MalformedURLException e) {
Log.e(TAG, "", e);
} catch (IOException e) {
Log.e(TAG, "", e);
} finally {
close(bufferedReader);
}
return null;
}
private static void close(Reader reader) {
if (reader != null) {
try {
reader.close();
} catch (IOException exp) {
Log.e(TAG, "", exp);
}
}
}
Yes you need to close the inputstream first and close httpconnection next. As per javadoc.
Each HttpURLConnection instance is used to make a single request but the underlying network connection to the HTTP server may be transparently shared by other instances. Calling the close() methods on the InputStream or OutputStream of an HttpURLConnection after a request may free network resources associated with this instance but has no effect on any shared persistent connection. Calling the disconnect() method may close the underlying socket if a persistent connection is otherwise idle at that time.
Next two questions answer depends on purpose of your connection. Read this link for more details.
I believe the requirement for calling setDoInput() or setDoOutput() is to make sure they are called before anything is written to or read from a stream on the connection. Beyond that, I'm not sure it matters when those methods are called.
I am using the following code to connect and retrieve the UTC time from an AtomicTime server from an Android device:
public static final String ATOMICTIME_SERVER="http://132.163.4.101:13";
BufferedReader in = null;
try
{
URLConnection conn = new URL(ATOMICTIME_SERVER).openConnection();
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String atomicTime;
while (true)
{
if ( (atomicTime = in.readLine()).indexOf("*") > -1)
{
break;
}
}
... do something
}
catch ...
It does not return any data. When accessing the URL from a browser, we get the following:
55884 11-11-19 07:40:22 00 0 0 824.5 UTC(NIST)
Can anyone help?
String atomicTime = "";
try
{
Socket socket = new Socket("132.163.4.101", 13);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
in.readLine(); // Ignore leading blank line
atomicTime = in.readLine();
socket.close();
}
catch....
This is because there is no HTTP service on TCP port 13. There is daytime service. You should use Socket instead of URLConnection. Or maybe find some NTP implementation for Android.