Bluetooth Socket InputStream Read Problem => IOException Socket closed

  • Antworten:3
  • OffenNicht stickyBentwortet

12.05.2012 21:16:34 via Website

Hallo zusammen,

ich doktore da jetzt schon den ganzen Tag dran rum und weiß langsam nichtmehr was ich noch testen soll. Ich hab ne app geschrieben, die lädt man auf 2 geräte drauf, beim starten sagt man dann welche der beiden geräte der server sein soll, dieser startet dann wie bei android developers beschrieben einen AcceptThread. dann wählt man bei der anderen app natürlich client aus, gibt die mac adresse des servers an und dann wird dort ein connectThread gestartet. dann verbinden sich die beiden geräte und es wird bei beiden ein connectedthread gestartet um zu kommunizieren.

1private class ConnectedThread extends Thread {
2 private final BluetoothSocket mmSocket;
3 private final InputStream mmInStream;
4 private final OutputStream mmOutStream;
5
6 public ConnectedThread(BluetoothSocket socket) {
7 mmSocket = socket;
8 InputStream tmpIn = null;
9 OutputStream tmpOut = null;
10
11 // Get the input and output streams, using temp objects because
12 // member streams are final
13 try {
14 tmpIn = socket.getInputStream();
15 tmpOut = socket.getOutputStream();
16 } catch (IOException e) {
17 }
18
19 mmInStream = tmpIn;
20 mmOutStream = tmpOut;
21 }
22
23 public void run() {
24 byte[] buffer = new byte[1024]; // buffer store for the stream
25 int bytes; // bytes returned from read()
26
27 // Keep listening to the InputStream until an exception occurs
28 while (true) {
29 try {
30 //if(mmInStream.available() > 0){
31 // Read from the InputStream
32 bytes = mmInStream.read(buffer);
33 // Send the obtained bytes to the UI activity
34 mHandler.obtainMessage(SCDActivity.MESSAGE_READ, bytes, -1,
35 buffer).sendToTarget();
36 Log.i("Bluetooth ConnectedThread run()", "es wurde zumindest versucht etwas zu lesen");
37 //}
38 } catch (IOException e) {
39 //TODO Hier krachts
40 Log.e("Bluetooth ConnectedThread run()", "disconnected", e);
41 break;
42 }
43
44
45
46
47
48 }
49 }
50
51 /* Call this from the main activity to send data to the remote device */
52 public void write(byte[] bytes) {
53 try {
54 Log.i("Bluetooth ConnectedThread write()", "Es wurde etwas geschrieben...");
55 mmOutStream.write("test".getBytes());
56 } catch (IOException e) {
57 Log.e("Bluetooth ConnectedThread write()", "write failed", e);
58 }
59 }
60
61 /* Call this from the main activity to shutdown the connection */
62 public void cancel() {
63 try {
64 mmSocket.close();
65 } catch (IOException e) {
66 }
67 }
68 }

jenachdem welchen dienst (sever oder client) ich an die LogCat hänge bekomme ich unterschiedliche Fehlermeldungen:

entweder "Socket closed" (Client)
oder "Software caused connection abort" (Server)

beides mal wird es in dieser Zeile ausgelöst:
bytes = mmInStream.read(buffer);

hatte da schon ein synchronized block drum rum ich hab die read methode schon mit allem möglichen ersetzt, bringt alles nix... ich hab die zeile mal auskommentiert, dann hats super funktioniert... ist aber natürlich clever wenn man zwar senden aber nix empfangen kann....

vielleicht hat ja irgendwer von euch noch nen denkanstoß... wenn ihr mehr details braucht, bitte einfach fragen!

vielen dank schonmal im Voraus!
jeod


Lösung: habe beim callen des ConnectedThreads das Canceln aller vorher benötigten Threads weggelassen... jetzt funktionierts einwandfrei =)

— geändert am 14.05.2012 18:36:20

27.05.2012 01:14:46 via Website

Hi,

Kannst du evtl kurz deinen aktualisierten code posten? Ich habe aktuell das gleiche problem.

Meine thread abfolge:
Main thread started accpt thread.
Bei connection ruft accept thread einen connected thread auf und beendet sich dann selbst.

Kannst du mir helfen mein problem zu finden?

Danke

29.05.2012 12:12:53 via Website

Hi,

Danke fürs hochladen. Ich hab meinen und deinen Code verglichen und kaum Unterschiede feststellen können.

Habe das Problem aber nun gefunden: 2 Nachrichten wurden als 1 Nachricht gelesen und verarbeitet. So hat der Client nicht alles gelesen was der Server geschickt hat und andersrum. Nun schicke ich als erstes immer die Nachrichtengröße mit und nutze einen DataInputStream/DataOutputStream statt eines reinen InputStream/OutputStream:

1public void write(byte[] buffer) {
2 try {
3 mmOutStream.writeInt(buffer.length);
4 mmOutStream.write(buffer);
5 mmOutStream.flush();
6 } catch (IOException e) {
7 if (D) Log.e(TAG, "( ID: " + connectionID + "): Exception during write", e);
8 }
9 }

Natürlich beim lesen genauso:
1public void run() {
2 if (D) Log.i(TAG, "( ID: " + connectionID + "): START");
3 canceled = false;
4
5 // Keep listening to the InputStream while connected
6 while (true) {
7 try {
8
9 // Read from the InputStream
10
11
12
13 //getting messagesize in bytes
14 int messagesize = mmInStream.readInt();
15 byte[] buffer = new byte[messagesize];
16 mmInStream.readFully(buffer, 0, messagesize);
17
18 // Send the obtained bytes to the UI Activity
19 Bundle bundle = new Bundle();
20 [...]
21 handler.sendMessage(msg);
22 }
23
24
25 } catch (IOException e) {
26
27 if (D) {
28 if ( canceled){
29 Log.i(TAG, "( ID: " + connectionID + "): canceled");
30 }else{
31 Log.e(TAG, "( ID: " + connectionID + "): disconnected", e);
32 }
33 }
34 this.bluetooth.connectionLost(connectionID);
35 break;
36 }
37 }
38 if (D) Log.i(TAG, "( ID: " + connectionID + "): END");
39 }

Vielleicht hilft es ja jemanden.....