2009-08-21 31 views
5

Tôi hiện đang viết một ứng dụng trên Blackberry để gửi và nhận một số dữ liệu thô tới một thiết bị dựa trên TCP khác trên mạng của tôi. Tôi đang gặp vấn đề tương tự trong giả lập Blackberry w/một mô phỏng MDS chạy và sử dụng một điện thoại vật lý nói chuyện với máy chủ MDS của công ty tôi. Lưu ý vấn đề này không xảy ra khi sử dụng wifi trực tiếp và không qua MDS.Sự cố khi sử dụng SocketConnection với Blackberry bằng MDS

Vấn đề là hàm available() trên InputStream trả về số không trừ khi tôi gọi hàm read() trước tiên. Nếu tôi gọi đọc đầu tiên (biết có một số dữ liệu có sẵn .. cảm ơn bạn wireshark) dữ liệu trở lại, và các cuộc gọi tiếp theo để có sẵn() chỉ ra những dữ liệu còn lại mà tôi đã không đọc. Vấn đề là tôi không phải lúc nào cũng được đảm bảo rằng dữ liệu sẽ ở đó và vì vậy tôi có thể chặn. Có ai nhận thức được điều này, và đây có phải là một vấn đề hay cái gì đó là do thiết kế?

Có ai biết cách kiểm tra nếu (các) phương thức read() sẽ chặn trước khi gọi chúng sang một bên không?

Đây là cơ bản những gì tôi đang làm:

 
SocketConnection s = (SocketConnection)Connector.open("socket://1.2.3.4:port;deviceside=false", Connector.READ_WRITE); 

OutputStream o = ((StreamConnection)s).openOutputStream(); 
InputStream i = ((StreamConnection)s).openInputStream(); 

o.write("hello"); 
Thread.sleep(sometime); 
if (i.available() > 0) { 
    byte[] data = new data[10]; 
    int bytesRead = i.read(data); 
    System.out.println("Read [" + new String(data) + "] (bytes = " + bytesRead + ")"); 
} 

tôi phải nhận xét ra nếu có điều kiện để làm việc này.

+0

Nó có thể chặn - nhưng đó có phải là vấn đề nếu mạng của bạn nằm trên một chuỗi riêng biệt không? – lilbyrdie

+0

Tôi nghĩ rằng tôi đã đọc ở đâu đó trong các tài liệu mà hành vi được chỉ định này có sẵn. Như libyrdie nói chủ đề là bạn của bạn. Tôi quay lên một sợi chỉ để đọc và chỉ để nó chặn. – Richard

+0

Bình thường thì không sao.Vấn đề là chúng tôi đang cố gắng tìm hiểu xem một thiết bị có mặt hay hoạt động chính xác hay không bằng cách xem liệu nó có phản ứng với một ping TCP cụ thể hay không. Chỉ cho phép đọc để chặn không giúp đỡ nhiều. Về cơ bản chúng tôi phải sinh ra sợi chỉ và sau đó giết nó sau X giây. Đây không phải là quá khó, nhưng không lý tưởng. Điều này sẽ không gây phiền toái nếu điều này không hoạt động khi sử dụng Wifi trực tiếp thay vì kết nối MDS. Nếu bạn sử dụng Wi-Fi trực tiếp, công trình sẽ tuyệt vời. – borq

Trả lời

0

Như tôi đã nêu trong phần nhận xét ở trên, tôi cần một cách để xác định xem thiết bị tôi đang kết nối không có ở đó không và tôi làm điều đó bằng cách xem liệu 'ping' của chúng tôi có trả về bất kỳ dữ liệu nào không. Nếu thiết bị không ở đó, thiết bị sẽ chặn. Tôi không thể dựa vào hành vi đó. Một vấn đề khác nảy sinh trong khi giải quyết điều này là các phương thức read (...) của khối lớp RIM InputStream nếu bạn cung cấp một bộ đệm lớn hơn dữ liệu bạn muốn quay trở lại. Nhưng làm thế nào tôi phải biết có bao nhiêu dữ liệu có nếu có() trả về 0? Đọc byte-by-byte là về cách duy nhất để làm điều này, nhưng nó vẫn chặn nếu không có dữ liệu.

Để giải quyết vấn đề này, tôi đã theo chủ đề của câu trả lời thứ nhất, nhưng tôi đặt phương thức này vào chủ đề riêng của nó và ghi nó vào bộ đệm byte riêng biệt. Tôi đã tạo một lớp mở rộng InputStream và đã có sẵn() và đọc (...). Có sẵn trả về bao nhiêu byte trong bộ đệm byte, và chỉ đọc trả lại tuy nhiên phần lớn là trong bộ đệm hoặc tuy nhiên nhiều yêu cầu người gọi, tùy theo số nào ít hơn.

Thiết lập này cho phép tôi sử dụng giao diện InputStream, nhưng đằng sau hậu trường, nó chỉ là chuỗi trình đọc đang chạy liên tục cho đến khi kết nối bị ngắt. Tại thời điểm đó đọc, nếu bị chặn, sẽ ném một ngoại lệ để cho biết kết nối đã đóng. Hành vi này là tốt vì nó có thể dễ dàng xử lý.

Nhờ tất cả những ai đã giúp đỡ về vấn đề này. Suy nghĩ của bạn giúp hướng tới giải pháp.

3

Hợp đồng chung của phương thức InputStream.available() là "Trả về số byte có thể đọc (hoặc bỏ qua) từ luồng đầu vào này mà không chặn người gọi tiếp theo của phương thức cho luồng đầu vào này . " Do đó trong hầu hết các triển khai, nó không đảm bảo rằng nó sẽ trả về Độ dài nội dung của luồng đang được đọc. Do đó, tốt hơn là đọc nó theo cách sau đây

byte[] readFromStream(InputStream is) throws IOException 
{ 
    byte[] data = new byte[4096]; 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    DataOutputStream dos = new DataOutputStream(baos); 

    int count = is.read(data, 0, data.length); 
    while (count != -1) 
    { 
     dos.write(data, 0, count); 
     count = is.read(data, 0, data.length); 
    } 

    data = baos.toByteArray(); 

    return data; 
} 

Bạn gọi phương thức readFromStream() và nhận byte [] trả về.

+0

Chính xác. Tương tự trên Android. – yanchenko

Các vấn đề liên quan