2015-05-25 13 views
9

Tôi đã xóa liên kết mạng không có kết quả. Chúng tôi đang đối mặt với một vấn đề mà một số thiết bị Android bị mất gói dữ liệu nghiêm trọng. Để cung cấp một số nền, ứng dụng kết nối với một Wifi cụ thể và tìm kiếm các gói UDP được phát sóng trên cổng 17216. Các gói này có kích thước 832 byte, không bao gồm các tiêu đề được bao bọc và được gửi với tốc độ bình thường là bốn giây.Mất gói UDP nghiêm trọng trên một số thiết bị Android

Chúng tôi chỉ gặp sự cố trên hai thiết bị, máy tính bảng Turbox Rubik II cấp thấp và ASUS Memo Pad HD 7. Các thiết bị khác mà chúng tôi đã thử nghiệm (điện thoại và máy tính bảng) đều thu thập các gói theo quy định thường xuyên khoảng thời gian.

Chức năng tiếp nhận các gói tin là thế này:

public void run() 
{ 
    while (isUDPServerRunning) 
    { 
     try 
     { 
      socket.receive(packet); 

      ProcessRawPacketData(); 

      DisplayLoggingInfo(); 

     } 
     catch (IOException e) 
     { 
      Log.e("receive", e.getMessage()); 
      e.printStackTrace(); 
     } 
    } 
} 

Và đó là một phần của một Runnable. Các ổ cắm được tạo ra như sau:

byte[] buffer = new byte[1024]; 

DatagramSocket socket; 
DatagramPacket packet = new DatagramPacket(buffer, buffer.length); 

với các ổ cắm được khởi tạo trong phương pháp onCreate() gia hạn Service của chúng tôi:

socket = new DatagramSocket(SERVERPORT); 

các gói tin đang được nhận bởi module Wifi. Chúng tôi đã xác nhận rằng bằng cách rooting một trong các thiết bị và cài đặt một gói sniffer, do đó, vấn đề bằng cách nào đó phải được mã liên quan.

Trên các gói thiết bị bị ảnh hưởng được nhận một cách chính xác trong vài giây và sau đó có hoàn toàn bỏ học kéo dài trong vài giây, vì vậy tôi ước tính mất hơn 50%.

Mọi trợ giúp sẽ được đánh giá cao. Chúng tôi đang kéo tóc ra.

Cập nhật Tôi đã nhầm lẫn về gói sniffer. Dường như gói sniffer cũng mất một số gói tin có liên quan trên thiết bị gốc. Đôi khi,, mặc dù, chỉ cần bắt đầu gói tin sniffer khắc phục vấn đề! Bật/tắt Bluetooth như được đề xuất bên dưới dường như không tạo nên sự khác biệt. Đây có phải là vấn đề phần cứng khác không?

Cập nhật 2 Dưới đây là một ví dụ về các bản ghi Tôi in ngay sau khi dòng socket.receive(). Chú ý cách nó bỏ qua các gói trị giá nửa phút và sau đó hoạt động tốt trong vài giây.

05-25 15:44:38.670: D/LOG(4393): Packet Received 
05-25 15:44:38.941: D/LOG(4393): Packet Received 
05-25 15:45:09.482: D/LOG(4393): Packet Received 
05-25 15:45:09.716: D/LOG(4393): Packet Received 
05-25 15:45:09.928: D/LOG(4393): Packet Received 
05-25 15:45:10.184: D/LOG(4393): Packet Received 
05-25 15:45:10.451: D/LOG(4393): Packet Received 
05-25 15:45:10.661: D/LOG(4393): Packet Received 
+0

bạn đã thử sử dụng các công cụ kiểm tra băng thông hoặc chẩn đoán giao diện mạng trên các thiết bị đó chưa? –

+0

Treo trong đó. Đọc phần này để lấy cảm hứng: http://blog.krisk.org/2013/02/packets-of-death.html – CenterOrbit

Trả lời

3

Mất gói (như bạn đã biết, tất nhiên) có thể xảy ra ở nhiều giai đoạn dọc theo truyền:

  1. gửi từ máy chủ
  2. truyền qua mạng
  3. tiếp nhận vật lý tại khách hàng và xử lý trong phần cứng
  4. Xử lý/đệm gói trong hạt nhân/HĐH
  5. Xử lý/đệm gói trong ứng dụng của bạn.

Bạn có thể nhanh chóng kiểm tra xem điểm 1 hoặc 2 có phải là vấn đề hay không bằng cách để các thiết bị khác nghe cùng một chương trình phát sóng trong khi kết nối với cùng một bộ định tuyến Wifi. Có vẻ như bạn đã làm điều này và không có vấn đề gì. (Lưu ý rằng một gói bị bỏ ở bước 2 (hoặc đôi khi thậm chí 1) có thể không bị thiếu trong bãi chứa WireShark nếu bạn chạy nó trên máy chủ.)

Do đó, từ 3 đến 5 có thể là vấn đề và họ có thể khó hơn một chút để tách ra.

Dưới đây là một vài điều mà có thể giúp:

  • Giống như @Mick đề nghị, không chỉ in ra khi bạn nhận được gói tin, nhưng cung cấp cho mỗi gói một số ID tăng để tìm ra cho dù bạn thực sự bị mất gói hay liệu nó có bị trì hoãn hay không.
  • di chuyển mã gói tin nhận bạn vào thread riêng của mình (nếu nó chưa được) và set the priority của thread đó để MAX_PRIORITY để giảm thiểu cơ hội mà mã của bạn đang nắm giữ lên dòng trưa. Cho rằng Memo Pad là một máy 1.2GHz quad-core, MAX_PRIORITY thậm chí không cần thiết, nhưng nếu bạn hiện không chạy vòng lặp nhận trong chuỗi chuyên dụng riêng của nó, bạn có thể thấy bất cứ lúc nào. Nếu điều này sửa chữa mọi thứ, chỉ cần có một vòng lặp nhận tối thiểu các gói tin vào hàng đợi bộ đệm của riêng bạn và có một luồng độc lập xử lý chúng.
  • Kiểm tra/tăng kích thước bộ đệm gói để nhận gói thông qua setReceiveBufferSize(...) (more verbose Java reference here). Đảm bảo bạn chỉ định kích thước có thể chứa nhiều gói. Cho rằng chạy các gói sniffer đôi khi dường như để giúp mọi thứ, nó âm thanh như có thể có một số thiết lập socket có thể cải thiện mọi thứ, mà sniffer xảy ra để thiết lập.
  • Trên máy chủ bạn cũng có thể thêm thẻ vào gói cho tất cả các thiết bị liên quan cách xử lý gói.Nếu bạn gọi setTrafficClass(IPTOS_RELIABILITY), bạn đang yêu cầu tất cả mọi người tham gia để tối ưu hóa xử lý gói của họ cho độ tin cậy tối đa. Không phải mọi thiết bị đều quan tâm, nhưng nó có thể tạo ra sự khác biệt.
  • Bạn có thể thử sử dụng DatagramChannels thay vì DatagramSockets và sau đó sử dụng select() để chờ gói tiếp theo để đọc. Mặc dù về mặt kỹ thuật này không nên tạo sự khác biệt, đôi khi việc sử dụng một cuộc gọi API khác có thể cung cấp giải pháp cho một vấn đề.
  • Thật không may Android là một môi trường rất không đồng nhất, nơi nhiều nhà sản xuất sẽ cung cấp các mô-đun hạt nhân riêng của họ, vv Điều này cũng giới thiệu nhiều không tương thích hoặc hành vi phi tiêu chuẩn ở khắp mọi nơi. Bạn có thể tìm thấy một ROM tùy chỉnh (Cyanogen, vv?) Cho một hoặc cả hai thiết bị của bạn. Nếu cài đặt thay vì ROM của nhà máy khắc phục sự cố, thì đó là lỗi trong trình điều khiển mạng được cung cấp bởi nhà sản xuất, trong trường hợp đó, bạn có thể gặp may khi tìm một công việc xung quanh hoặc bạn có thể gửi báo cáo lỗi với họ, nhưng nói chung, bạn có thể chỉ cần chọn các thiết bị đó là không được hỗ trợ trong Cửa hàng Play để tránh các đánh giá không hợp lệ ...

Cuối cùng, đây là vấn đề cần khắc phục sự cố:

Thêm một số mã cho khách hàng của bạn phát hiện các gói bị bỏ và nếu tỷ lệ thả quá cao, mở kết nối TCP đến máy chủ thay thế, sau đó sẽ đảm bảo gửi gói. Cho rằng các gói của bạn nhỏ và không thường xuyên và chỉ có một vài thiết bị sẽ cần phải sử dụng cơ chế này, tôi không nghĩ rằng điều này sẽ gây ra một vấn đề cho tải máy chủ của bạn. Nếu bạn không có cách nào để thay đổi mã máy chủ để cung cấp luồng TCP, bạn có thể viết một máy chủ proxy độc lập thu thập các gói UDP và làm cho chúng có sẵn thông qua TCP. Nếu bạn có thể chạy nó trên cùng một máy với máy chủ gốc, bạn thậm chí còn biết địa chỉ IP của nó là gì (giống như địa chỉ nguồn của các gói UDP đã đến).

+0

tôi đang trải nghiệm cùng một vấn đề, bạn có thể xem http://stackoverflow.com/questions/38891610/packet-loss-while-receiving-udp-broadcast-in-android sẽ là một trợ giúp tuyệt vời –

0

này nghe có vẻ rất giống với triệu chứng can thiệp Bluetooth có thể được nhìn thấy trên Android (và iOS - trên thực tế bất cứ điều gì với WiFi và Bluetooth với nhau) thiết bị.

2,4 GHz WiFi và Bluetooth có cùng băng thông và có thể ảnh hưởng lẫn nhau - trên một số thiết bị, điều này rõ ràng có thể do bố cục bên trong. Nó cũng có thể là bạn có thể thấy nó trên một số thiết bị và không phải là những người khác vì các phiên bản WiFi mà họ hỗ trợ - wifi dựa trên 5GHz mới hơn không can thiệp vào bluetooth theo cùng một cách, nhưng một số Android cũ hơn hoặc cơ bản hơn các thiết bị có thể không hỗ trợ điều này.

Bạn có thể kiểm tra xem đây có phải là nguyên nhân khá dễ dàng bằng cách tắt bluetooth trên thiết bị trong khi thử nghiệm (nếu ứng dụng của bạn có thể hoạt động mà không có bluetooth).

+0

Cảm ơn! Điều này nghe giống như một dẫn tốt, nhưng chuyển đổi bluetooth off/on không có hiệu lực. Ngoài ra, gói sniffer đã xác nhận rằng các gói tin đã được nhận, vì vậy tôi không nghĩ rằng đây là nguyên nhân. –

+0

@ KristianD'Amato bạn có thể chia sẻ nhật ký từ các lần chạy các gói bị mất không? – Mick

+0

Có Mick, xem cập nhật của tôi ở trên. Cảm ơn. –

1

Chỉ là một phỏng đoán hoang dã, nhưng tính toán của bạn trong bao lâu sẽ mất bao lâu?Có thể bộ đệm được cấp phát cho ổ cắm đầy và bắt đầu thả các gói không?

Tôi biết, điều này nghe có vẻ khó xảy ra với tốc độ truyền tải khoảng 4 KB/s ... Nhưng nếu tính toán của bạn mất hơn 250 ms thì điều này sẽ sớm xảy ra. Điều này cũng sẽ giải thích tại sao một số thiết bị hoạt động như một sự quyến rũ, và những thiết bị khác thì không.

Bạn đã cố gắng loại bỏ các tính toán và chỉ in thông báo "gói đã nhận" để gỡ lỗi?

+0

nếu hai gói được gửi cùng một lúc, bạn có thể vui lòng kiểm tra http://stackoverflow.com/questions/38891610/packet-loss-while-receiving-udp-broadcast-in-android –

1

Điều thú vị là cả hai thiết bị đang gặp phải mất gói UDP đều có Mediatek SoC. Các thiết bị thử nghiệm khác của bạn có cùng chipset không?

Đây có thể là lỗi trong trình điều khiển cho Wi-Fi của các SoC đó. Vì nó chỉ xuất hiện với UDP, và không phải luôn luôn 100%, nó có thể đã không được mọi người chú ý cho đến bây giờ.

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