I am able to connect to an external paired bluetooth hardware first time. After that if i repeat connect/disconect procedures sometimes getting exception.
Exception = read failed, socket might closed or timeout, read ret: -1
and after many trials able to connect again.Sometimes second trial itself is successful
The issue is observed with Devices:Nexux7(version 4.3) and MotoG(Kitkat)
Code for connection:
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(devAddress);
socket = device.createRfcommSocketToServiceRecord(MY_UUID);
and calling socket.connect() from asynctask
Code for closing socket:Subject
if (in != null) {
Logger.loge(CLASS_NAME + "." + "resetConnection", "in != null");
try {
in.close();
} catch (Exception e) {
// Log.d(TAG,"exception in closing inputstream - " + e.getMessage());
}
in = null;
}
if (out != null) {
Logger.loge(CLASS_NAME + "." + "resetConnection", "out != null");
try {
out.close();
} catch (Exception e) {
// Log.d(TAG,"exception in closing outputstream - " + e.getMessage());
}
out = null;
}
if (socket != null) {
Logger.loge(CLASS_NAME + "." + "resetConnection", "socket != null");
try {
socket.close();
} catch (Exception e) {
//Log.d(TAG,"exception in closing socket - " + e.getMessage());
}
socket = null;
}
I have followed the links
https://groups.google.com/forum/#!topic/android-developers/UxY5xME6V5s
Android Bluetooth: java.io.IOException: Service discovery failed
Disconnect a bluetooth socket in Android
android bluetooth can't connect
None of the solution provided help me to solve the issue.
Any help will be appreciated...
Thanks
I had encountered a similar problem when I built an app involving bluetooth connectivity. After searching for a long time, I found this solution.
The Actual problem is once both the device the is connected, the socket will be open. When either one of the socket is closed, other one is not closed.When you try to reconnect the other device ll not accept the new Socket.
The solution is when any one gets disconnect you need to re-initialize the connection service on both the side,ie you need to close the socket properly on both the side. and go back to the listen mode. then only the new socket connection will accept.click Here code reference using AndroiddChat example.
Related
I try to implement a Java Proxy for Http (Https will be the extension after Http works). I found a lot of resources on the Internet and try to solve all problems on my own so far. But now I come to a point where I stuck.
My Proxoy does not load the full http websites. I get a lot of error messages with the socket is already closed. So I think I try to send something over a Socket that is closed.
My Problem is now. I can not see why it is like this. I think a lot over the problem but I can not find the mistake. From my side The Sockets only get closed when the server close the connection to my Proxy Server. This happen when I read a -1 on the input stream from the server.
I would be happy for any help :-)
greetings
Christoph
public class ProxyThread extends Thread {
Socket client_socket;
Socket server_socket;
boolean thread_var = true;
int buffersize = 32768;
ProxyThread(Socket s) {
client_socket = s;
}
public void run() {
System.out.println("Run Client Thread");
try {
// Read request
final byte[] request = new byte[4096];
byte[] response = new byte[4096];
final InputStream in_client = client_socket.getInputStream();
OutputStream out_client = client_socket.getOutputStream();
in_client.read(request);
System.out.println("---------------------- Request Info --------------------");
System.out.println(new String(request));
Connection conn = new Connection(new String(request));
System.out.println("---------------------- Connection Info --------------------");
System.out.println("Host: " + conn.host);
System.out.println("Port: " + conn.port);
System.out.println("URL: " + conn.URL);
System.out.println("Type: " + conn.type);
System.out.println("Keep-Alive:" + conn.keep_alive);
server_socket = new Socket(conn.URL, conn.port);
InputStream in_server = server_socket.getInputStream();
final OutputStream out_server = server_socket.getOutputStream();
out_server.write(request);
out_server.flush();
Thread t = new Thread() {
public void run() {
int bytes_read;
try {
while ((bytes_read = in_client.read(request)) != -1) {
out_server.write(request, 0, bytes_read);
out_server.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t.start();
int bytes_read;
while ((bytes_read = in_server.read(response)) != -1) {
out_client.write(response, 0, bytes_read);
out_client.flush();
//System.out.println("---------------------- Respone Info --------------------");
//System.out.println(new String(response));
}
//System.out.println("EIGENTLICH FERTIG");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
client_socket.close();
server_socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
EDIT:
My HTTP Proxy now works. The Answer is pretty helpfull once you understand what is ryl going on. If you come hear to find a solution this questions may help you:
Does the client send a request only to one Website / Webserver? Means do we always have the same port / hostname?
The Loop from the answer is very usefull but think where to place it?
Last think: Thanks #EJP its working your reply was very usefull. It only tooks a time to understand it!
You are making all the usual mistakes, and a few more.
The entire request is not guaranteed to arrive in a single read. You can't assume more than a single byte has arrived. You have to loop.
You aren't checking for end of stream at this stage.
You need a good knowledge of RFC 2616 to implement HTTP, specifically the parts about Content-length and transfer encoding.
You cannot assume that the server will close the connection after sending the response.
Closing either the input or the output stream or a socket closes the socket. This is the reason for your SocketException: socket closed.
When you get to HTTPS you will need to look at the CONNECT verb.
Flushing a socket output stream does nothing, and flushing inside a loop is to be avoided,
Hi am trying to send a binary message to a server with the IP and Port:
192.168.2.101:10001
The socket is reopened every 50 messages.
If I run the application normally I get a java.net.ConnectException in line 5, even though I can ping and telnet the server.
If I debug the application I get a java.net.SocketException at a different line (11), also sometimes the first message seems to get through without any errors.
private void sendMessage(String message, int relaisId, long timestamp) {
try {
if (connCount > 50) {
s = new Socket(ip, port); //RUN NORMALLY: java.net.ConnectException: Connection refused: connect
connCount=0;
}
outputStream = s.getOutputStream();
outputStream.write(message.getBytes());
outputStream.write(new byte[]{0});//DEBUG: java.net.SocketException: Connection reset by peer: socket write error
outputStream.flush();
connCount++;
} catch (UnknownHostException ex) {
logger.error("Host not found: " + ip + ":" + port, ex);
connCount=51;
retryMessage(message, relaisId, timestamp);// basically sleep 3s then call sendMessage
} catch (IOException ex) {
logger.error("Error at Relais No. " + relaisId + ": " + ip + ":" + port, ex);
connCount=51;
retryMessage(message, relaisId, timestamp); // basically sleep 3s then call sendMessage
} finally {
try {
if (connCount > 50 && s != null) {
s.close();
}
} catch (IOException ex) {
logger.error("IOException", ex);
}
}
}
Any help or analysis tools are very much appreciated :)
I found the solution. In my program different Threads send messages to external hardware components over given IPs and Ports.
This error occured because a Thread accidently got initiated twice with the same IP address and port, resulting in timing conflicts while using the same socket.
Even more strange was, that this error started to occur permanently while changing the server machine, before it was only there sporadically and we thought it was a noise in the network communication.
Hope this is a help to anyone in the future :)
I am trying to print to a thermal printer via Bluetooth.
I was able to successfully print before on a Nexus 7 Device (both the first and second generations). However, when I copy pasted the exact same code on a different application and deployed it on an Asus Tablet, I suddenly got an IOException that tells me that my socket might be closed.
Here is my code:
public void onPrintReceipt(){
Toast.makeText(getApplicationContext(), "Printing", Toast.LENGTH_LONG).show();
try{
Set<BluetoothDevice> bdevices = bluetoothAdapter.getBondedDevices();
blueToothDevice = bluetoothAdapter.getRemoteDevice("00:01:90:EE:B2:52");
simpleComm(1);
}
catch(Exception ex){
Log.e("", "simpleComm() Catch Statement Entered");
}
}
protected void simpleComm(Integer port){
//InputStream tmpIn = null;
byte[] buffer = new byte[3]; //{65,65,53,53,49,52,65,66,67,68};
buffer[0] = (byte) 0x08;
buffer[1] = (byte) 0x99;
buffer[2] = (byte) 0x04;
OutputStream tmpOut;// = null;
bluetoothAdapter.cancelDiscovery();
Log.e(this.toString(), "Port = " + port);
try {
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
Method m = blueToothDevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
socket = (BluetoothSocket) m.invoke(blueToothDevice, port);
// assert (socket != null) : "Socket is Null";
if(socket.isConnected()){
socket.close();
}
socket.connect();
try {
Log.e(this.toString(), "************ CONNECTION SUCCEES! *************");
try{
//tmpIn=socket.getInputStream();
tmpOut = socket.getOutputStream();
//mmInStream = tmpIn;
mmOutStream = tmpOut;
out = new BufferedWriter(new OutputStreamWriter(mmOutStream));
}
catch(Exception ex){
Log.e(this.toString(), "Exception " + ex.getMessage());
}
//TODO print sequence starts here
//....snip snip a LOT of code
}
finally{
mmOutStream.flush();
mmOutStream.close();
socket.close();
}
}
catch (IOException ex){
Log.e(this.toString(), "IOException: " + ex.getMessage());
}
catch (NoSuchMethodException ex){
Log.e(this.toString(), "NoSuchMethodException: " + ex.getMessage());
}
catch (IllegalAccessException ex){
Log.e(this.toString(), "IllegalAccessException: " + ex.getMessage());
}
catch (InvocationTargetException ex){
Log.e(this.toString(), "InvocationTargetException: " + ex.getMessage());
}
}
And here is the error from the try-catch block:
IOException: read failed, socket might closed or timeout, read ret: -1
And now I am confused as to why there's suddenly an error when all I did was to deploy the code on a different device.
How can I proceed?
I see you use reflection to create your RFCOMM connection. This is pretty dangerous, I recently answered a question in that regard: How do Bluetooth SDP and UUIDs work? (specifically for Android)
Tl;dr: You are bypassing the SDP lookup mechanism that maps an UUID to an appropriate Bluetooth channel on the device you connect to. Your code ALWAYS connects to bluetooth channel 1. That might work initially/some cases - but could also be your problem. It depends on the receiving device.
You are creating an UUID. I guess (hope) you have it from the printer's documentation? But if you check your code, you will see that you are not using it to connect to the printer - which you absolutely should do (refer to the linked answer, for the whole story). Use createRfcommSocketToServiceRecord(uuid) to open your socket.
Since you are using the Nexus 7: I used two Nexus 7, a Nexus 4 and 10 other devices to test a bluetooth middleware for android I wrote. Especially the Nexus devices were pretty sensitive when the bluetooth was stressed by many concurrent calls leading to a completely useless bluetooth adapter until I power cycled them. Additionally I think to remember there was a bug in cases when I used this hacky reflection snippet that filled up the bt-adapter's channels until no one was left resulting in total bluetooth failure (I wasn't able to find the link to the related official android bug report, but there is one for the Nexus devices).
The below program causes this issue
EDITED:
import java.io.*;
import java.net.*;
public class smtpClient {
public static void main(String[] args) {
// declaration section:
// smtpClient: our client socket
// os: output stream
// is: input stream
Socket smtpSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
// Initialization section:
// Try to open a socket on port 25 : step 1
// Try to open input and output streams: step 2
try {
smtpSocket = new Socket("192.168.1.2", 1024);
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: hostname");
}
// If everything has been initialized then we want to write some data
// to the socket we have opened a connection to on port 25
if (smtpSocket != null && os != null && is != null) {
try {
// The capital string before each colon has a special meaning to SMTP
// you may want to read the SMTP specification, RFC1822/3
os.writeBytes("HELO\n");
os.writeBytes("MAIL From: k3is#fundy.csd.unbsj.ca\n");
os.writeBytes("RCPT To: k3is#fundy.csd.unbsj.ca\n");
os.writeBytes("DATA\n");
os.writeBytes("From: k3is#fundy.csd.unbsj.ca\n");
os.writeBytes("Subject: testing\n");
os.writeBytes("Hi there\n"); // message body
os.writeBytes("\n.\n");
os.writeBytes("QUIT");
// keep on reading from/to the socket till we receive the "Ok" from SMTP,
// once we received that then we want to break.
String responseLine;
while ((responseLine = is.readLine()) != null) {
System.out.println("Server: " + responseLine);
if (responseLine.indexOf("Ok") != -1) {
break;
}
}
// clean up:
// close the output stream
// close the input stream
// close the socket
os.close();
is.close();
smtpSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
}
Console Log :
Couldn't get I/O for the connection to: hostname
The program I took is from :
http://www.javaworld.com/jw-12-1996/jw-12-sockets.html?page=4
I have already tried modifying the port from 25 to 1024
I am running it on my local PC, so I am admin on this system, but not sure if there is any default firewall issue(running this in eclipse on windows 7)
As per your comments below : DO I need to make a listner, which mean to say a Server Socket, which will listen to smtp client requests
Answer is: according to details what you have provided, there is no listener running or machine with specified IP and port number.
UPD: then you are trying to connect to somewhere you do have to be sure that there is something which listens on other side, either writing your own server code or by using a 3rd party server/code to provide certain service on a port number you are trying to reach.
Why would you expect that there is a mail server running on machine with an address you've provided?
It sounds like some other program is using port 1024.
Try a different port.
I'm trying to manage a connection between my phone and another bluetooth device. I'm doing all this using java Android. This is the code I used for connecting the socket using my device:
First I find the Bluetooth device and I create the socket:
BluetoothDevice btNonin = null;
for (BluetoothDevice device : pairedDevices)
{
if (device.getName().contains("Nonin"))
{
// We found the device
exito = true;
try
{
// We create the socket
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
socket = (BluetoothSocket) m.invoke(device, 1);
socket.connect();
}
catch (Exception e)
{
Dialogs.showInfoDialog(NONIN_OFF, this);
}
}
}
Afther that I create the data bytes I want the remote bluetooth to receive using some code to convert ASCII to byte:
String[] parts = mensaje.split(" ");
String res = "";
if(parts != null && parts.length > 0)
{
for (String s : parts)
{
if (s.length() != 2)
break;
byte izq, der;
izq = (byte)char2ascii(s.charAt(0));
der = (byte)char2ascii(s.charAt(1));
byte aux2 = (byte)((izq << 4) + der);
res += (char)aux2;
}
}
And then I send the data to the bluetooth device:
// We send the data bytes
DataOutputStream dOut = new DataOutputStream(socket.getOutputStream());
dOut.writeBytes(res);
dOut.flush();
Until here it works fine. It sends the data bytes to my device. But then I want to wait for any response from my device, and then I try this:
//Waiting for response
DataInputStream dIn = new DataInputStream(socket.getInputStream());
try
{
byte response = '\u0000';
while (dIn.readByte() == '\u0000')
{
response = dIn.readByte();
}
Dialogs.showInfoDialog("Response: " + response, this);
}
catch (Exception e)
{
Dialogs.showInfoDialog("No se ha recibido respuesta: " + e.toString(), this);
}
But then, on the line where I make dIn.readByte it shows the message Error:
java.io.IOException: Connection reset by peer
And I don't know why the connection is reset or what happens, as I can debug the line:
DataInputStream dIn = new DataInputStream(socket.getInputStream());
With no mistakes, so I guess the socket is still opened... What is happening here?
Thank you so much for your help!
There are several causes of this problem. The typical cause is that you have written to a connection which has already been closed by the peer. In other words, an application protocol error.
Also your exception handling needs work. If you get any IOException on a socket other than a timeout you must close it, it is dead.
Ok, I tried adding some wait() functions and it seems it works... As it was a problem between timeouts of reading and writing. I think this post should work...
remove the line dOut.flush(); this is causing the connection reset.