2010-11-28 2 views
1

블루투스를 통한 SPP (Java의 경우 BlueCove API)를 사용하는 두 대의 PC간에 파일 (약 6 메가 바이트 크기의 MP3)을 전송하려고합니다. 나는 한 방향 (예를 들어, 클라이언트에서 서버로 하나의 파일)에서 잘 작동하는 파일 전송을 얻을 수 있지만, 같은 세션에서 반대 방향으로 데이터를 보내려고 할 때 (즉, 서버에서 파일을 전송할 때) 클라이언트에게), 프로그램이 멈추고 진행되지 않습니다. 전송이 잘 작동블루투스를 통한 SPP로 파일 송수신시 문제가 발생했습니다.

StreamConnection conn; 
OutputStream outputStream; 

outputStream = conn.openOutputStream(); 

.... 

outputStream.write(data); //Data here is an MP3 file converted to byte array 

outputStream.flush(); 

: 단순히 내가 예를 들어

. 하지만 시도하면 :

StreamConnection conn; 
OutputStream outputStream; 
InputStream inputStream; 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 

outputStream = conn.openOutputStream(); 
inputStream = conn.openInputStream(); 

.... 

outputStream.write(data); 
outputStream.flush(); 


int receiveData; 
while ((receiveData = inputStream.read()) != -1) { 
    out.write(receiveData); 
} 

클라이언트와 서버가 모두 멈추고 앞으로 나아 가지 않습니다. 나는 파일 전송이 어떤 시점에서 실제로 일어나고있는 것을 볼 수있다. 클라이언트를 죽이면 서버는 문제없이 하드 드라이브에 파일을 기록하기 때문이다. 다른 파일 또는 정수로 응답하려고 시도 할 수 있으며 여전히 작동하지 않습니다.

누구든지 문제가 무엇인지 알 수 있습니까? 나는 OBEX가 블루투스를 통한 파일 전송에 일반적으로 사용된다는 것을 알고 있지만, 내가해야 할 일에는 과도한 것처럼 보였다. 이 기능을 위해 OBEX를 사용해야합니까?

+0

클라이언트 측 코드 요약을 게시 할 수 있습니까? – lijie

+0

와이어 덤프 (어떤 종류의 스니퍼 사용)가 도움이 될 것입니다. [Wireshark] (http : //www.wireshark.org /)를 사용하여이 파일을 덤프하고이 질문에 첨부하십시오. – GreyCat

답변

1

확실히 SPP를 사용하여 응용 프로그램간에 파일을 전송할 수 있습니다 (응용 프로그램을 사용하여 양방향으로 보내고받을 경우). 코드 스 니펫에서 프로그램에 무엇이 잘못되었는지를 말하기는 어렵습니다. 데이터를 전송할 때 스트림이 다른 쪽을 가리 키도록 닫아야한다고 생각합니다. 전체 파일을 하나의 청크에 쓰더라도 SPP/Bluetooth 프로토콜 계층에서 조각화 될 수 있습니다. 다른 쪽 끝은 조각으로 수신 될 수 있으므로 전송 완료를 나타내는 프로토콜이 필요합니다.

0

ByteArrayOutputStream을 사용하기로 결정한 이유가 무엇입니까?

try { 
     try { 

      byte[] buf = new byte[1024]; 

      outputstream = conn.openOutputStream(); 
      inputStream = conn.openInputStream(); 

      while ((n = inputstream.read(buf, 0, 1024)) > -1) 
       outputstream.write(buf, 0, n);     

     } finally { 
      outputstream.close(); 
      inputstream.close(); 
      log.debug("Closed input streams!"); 
     } 
    } catch (Exception e) { 
    log.error(e); 
     e.printStackTrace(); 
    } 

그리고 당신은 같은 것을 할 수 OutputStream에 변환 : 다음 코드를보십시오이 경우,

byte currentMP3Bytes[] = outputStream.toString().getBytes(); 
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(currentMP3Bytes); 
+0

전에 네트워크를 통해 전송할 파일의 크기를 알지 못했기 때문에 ByteArrayOutputStream이 사용되었습니다. 파일이 노래이고 매우 커서 (20 분 길이의 오케스트라 악보로 생각할 수 있음) 또는 비교적 작을 수 있으므로 일반적인 크기의 버퍼를 할당하는 것은 비실용적이었습니다. 그것은 분명히 내가해온 연구를 통해 수집 한 것에서부터 그렇게하는 일반적인 방법입니다. – Chance

1

클라이언트 측 코드를 보지 않고 말을하기 어렵다하지만, 내 생각을 (즉, 먼저 쓰고 읽는 것 모두 같은) 코드를 실행하고 있다면, 읽기가 발생하기 전에 outputStream을 닫아야 할 필요가 있습니다 (그렇지 않으면 둘 다 다른 쪽에서 닫히기 위해 기다리고있을 것입니다) 루프, 왜냐하면 read()은 다른 쪽이 닫힐 때 -1만을 반환합니다).

스트림을 닫지 않아야하는 경우 읽기를 중지하는 조건은 -1을 기다릴 수 없습니다. (따라서 파일 크기를 먼저 전송하거나 다른 메커니즘을 전송하도록 변경하십시오).

2

두 프로그램이 수신 통화 차단에 방해가되어 다른 끝에서 뭔가 말하기를 기다리는 것처럼 간단 할 수 있습니다 ... 로그 문을 톤 추가하여 각 프로그램의 상태를 볼 수 있습니다 (예 : 그래서 "수신 시도", "xxx 데이터 얻기", "회신 시도"등과 같은 실황 논평을 제공하거나 디버깅을 설정하고, 멈출 때까지 기다린 다음 한 단계를 중단하고 단일 단계를 중단합니다 그것.

+0

두 프로그램이 모두 수신 호출을 차단하고있는 것처럼 보입니다. 쓰기 작업은 비 블로킹이며 출력 스트림에 쓰는 것은 전송이 완료되었음을 나타내는 아무 것도 반환하지 않습니다. 어쨌든 전송이 연결을 청취하기 시작할 때까지 계속 기다릴 필요가 없습니다 (for-loop에서 한 번에 한 바이트 씩 작성하거나 영원히 걸릴 가능성이있는 다른 변형). inputStream.read()를 호출하자 마자 출력이 분명히 중단됩니다. – Chance

+0

비 차단 모드 또는 쿼리 데이터 가용성에 넣는 방법을 알아낼 수 없다면 (문서는 InputStream.available()의 안정성에 대해 열정보다 덜하지만 맹목적으로 읽는 것보다 낫습니다) 다른 스레드에서 읽는 방법으로이 문제를 해결할 수 있습니까? –

관련 문제