2015-01-13 3 views
1

현재 블루투스를 사용하여 두 개의 안드로이드 장치간에 데이터를 보내려고합니다. 블루투스 전송, 소켓 및 스트림과 관련하여 많은 질문을 읽었습니다. 지금까지 아무런 운도없이. 연결 부분이 작동 중입니다.안드로이드 블루투스 소켓 데이터 전송 및 라이프 사이클

BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(myOtherDeviceAdress); 
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID.fromString(myUUID)); 
socket.connect(); 

를 그리고 수신 측에 OutputStream

OutputStream mmout=tmp.getOutputStream(); 
byte[] toSend="Hello World!".getBytes(); 
mmout.write(toSend); 
mmout.flush(); 

를 사용하여 일부 데이터를 보내려고 : 내가 장치 주소는 다음 사용하여 연결을 열 수

mBluetoothServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("ccv_prototype", UUID.fromString(myUUID)); 
mBluetoothSocket = mBluetoothServerSocket.accept(3 * 1000); 
InputStream is = mBluetoothSocket.getInputStream(); 
BufferedReader r = new BufferedReader(new InputStreamReader(is)); 

그리고 그런 다음 현재 버퍼를 읽으려는 다른 버전입니다. 현재 :

int c; 
StringBuilder response = new StringBuilder(); 
try { 
    while ((c = r.read()) != -1) { 
     //Since c is an integer, cast it to a char. If it isn't -1, it will be in the correct range of char. 
     response.append((char) c); 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
String result = response.toString(); 
Log.d("MyTag", "Received String: " + result); 

여기 내 문제는 내가 OutputStream을 닫지 않으면받는쪽에 EOF가 수신되지 않는다는 것입니다. 그러나 mmout.close();을 추가하면 보내려는 메시지를 읽을 시간이 있기 전에 닫힙니다. 지금까지 유일한 생각은 특정 토큰을 EOF로 보내는 것입니다. 그러나 이것은 올바르게 들리지 않습니다.

무엇을 놓쳤습니까? 도움을 주시면 감사하겠습니다.

답변

1

간단한 대답은 예입니다. EOF를 나타 내기 위해 특정 토큰을 보내야합니다. Bluetooth 소켓에서 read() 작업을 수행하면 읽을 준비가 된 데이터가 있으면 즉시 데이터가 반환되거나 그렇지 않으면 또는 일부 데이터가있을 때까지 호출이 차단됩니다. IO 예외가 발생합니다 예 : 연결이 끊어짐). 따라서 Bluetooth 소켓 읽기 및 쓰기 작업의 경우 특히 Thread을 사용해야합니다. 당신이하려고하는 것은 BufferedReader에 의존하여 "더 이상의 데이터 없음"을 나타내는 -1을 반환합니다. 슬프게도, 이것이 작동하는 방식이 아닙니다. -1은 IO 예외 나 연결이 닫히는 경우에만 발생합니다.

귀하의 정보 부분 (즉, 귀하의 데이터 패킷)이 시작되고 끝나는 지점을 감지하거나 전반적인 통신 세션이 언제 끝났는지를 실제로 확인하는 것은 귀하가 귀하의 응용 프로그램 프로토콜 (또는 물론 기존의 통신 프로토콜 프로토콜). 이는 스트리밍 소켓을 통해 작동하는 모든 프로토콜에서 중요한 개념입니다. 살펴볼 좋은 예제는 HTTP입니다. 여러분이 알다시피 TCP를 통해 일반적으로 사용됩니다. HTTP를 간단히 살펴보면 (a) HTTP 프로토콜이 헤더를 사용하여 수신자에게 전체 HTTP "메시지"에 대해 예상되는 바이트 수를 알려주는 방법과 (b) HTTP 헤더가 어떻게 협상을 위해 사용되는지를 알려주는 방법 연결이 닫혀 야합니다. 할 수 없습니다. 송신자가 메시지 작성을 완료했는지 확인하기 위해 소켓 자체에 메소드를 사용하려고 시도합니다. 마찬가지로 한쪽 끝이 다른 쪽 끝에서 연결을 닫으 려한다는 것을 알고 있다면 응용 프로그램 프로토콜을 통해 협상해야합니다.

+0

귀하의 통찰력에 감사드립니다. 지금 내 마음에 분명해. 보낼 특정 토큰과 관련하여 조언이 있습니까? 나는 이것에 대한 몇 가지 문제를 가지고 성공하지 않고 특정 2 바이트 토큰을 보내려고했다. 빠르고 더러운 모드로 들어갔다가 순간에 줄 바꿈을 사용했는데 조금 컸습니다. – Nerkatel

+0

임의의 길이의 간단한 텍스트 문자열을 보내는 경우 줄 바꿈 문자를 사용할 수 있습니까? 또는 더 정교한 패킷 구조를 설계 할 수 있습니다. 예를 들어 페이로드 길이를 설명하는 헤더 필드로 시작합니다. 이것은 당신이하고 싶은 일과 당신이 연결을 통해 교환하려고 시도하고있는 일로 정확히 바뀝니다. – Trevor

관련 문제