- Siêu lớp và danh mục iOS/Objective-C
- object-c - -1001 lỗi khi NSURLSession vượt qua httpproxy và /etc/hosts
- java - Nhận địa chỉ url bằng lớp mạng
- ios - Âm thanh không phát trong thông báo đẩy
Tôi đang phát triển một ứng dụng Android (rõ ràng được viết bằng Java) và gần đây tôi đã cập nhật mã trình đọc UDP của mình. Trong cả hai phiên bản, tôi đã thiết lập một số bộ đệm và nhận được gói UDP:
byte[] buf = byte mới[10000];
ngắn [] soundData = ngắn mới [1000];
Gói DatagramPacket = DatagramPacket mới (buf, buf.length);
socket.receive(gói);
Trong phiên bản đầu tiên, tôi tập hợp dữ liệu lại từng byte một (thực tế là 16 mẩu dữ liệu âm thanh PCM):
cho (int i = 0; i < đếm; i++)
soundData[i] = (ngắn) (((buf[k++]&0xff) << 8) + (buf[k++]&0xff));
Trong các phiên bản mới hơn, tôi sử dụng một số công cụ Java thú vị mà tôi chưa biết khi bắt đầu:
bBuffer = ByteBuffer.wrap (buf);
sBuffer = bBuffer.asShortBuffer();
sBuffer.get (soundData, 0, đếm);
Trong cả hai trường hợp, "số" được điền chính xác (tôi đã kiểm tra). Tuy nhiên, dường như có một vấn đề mới xảy ra với âm thanh phát trực tuyến của tôi - có thể âm thanh phát trực tuyến của tôi không được xử lý đủ nhanh - điều này không có ý nghĩa gì đối với tôi. Rõ ràng mã bộ đệm được biên dịch thành nhiều hơn ba câu lệnh mã JVM, nhưng khi tôi bắt đầu việc này, có vẻ như giả định hợp lý rằng phiên bản thứ hai sẽ nhanh hơn phiên bản đầu tiên.
Nhìn bề ngoài, tôi không nhất quyết rằng mã của tôi phải sử dụng bộ đệm Java NIO, nhưng ít nhất thoạt nhìn, có vẻ giống như một con mo'betta' làm như vậy.
Có ai có đề xuất nào về trình đọc UDP Java đơn giản, nhanh chóng không? Có "cách tốt nhất" được chấp nhận rộng rãi để thực hiện việc này không?
谢谢,
câu trả lời hay nhất
Mã của bạn sẽ hiệu quả hơn nếu thay vì đọc gói thành một mảng byte (sao chép dữ liệu từ bộ đệm gốc vào mảng), sau đó gói nó vào một ByteBuffer mới (tạo một đối tượng mới) và chuyển đổi nó thành một ShortBuffer (tạo một đối tượng mới) Bạn chỉ đặt đối tượng một lần và tránh sao chép.
Bạn có thể thực hiện việc này bằng cách tạo socket bằng DatagramChannel.socket(), sau đó kết nối với nó như bình thường và lấy đối tượng DatagramChannel bằng socket.getChannel(). Đối tượng này sẽ cho phép bạn đọc các gói trực tiếp vào ByteBuffer hiện có (bạn nên tạo gói này bằng cách sử dụng ByteBuffer.allocateDirect để có hiệu quả tối đa). Sau đó, bạn chỉ cần sử dụng asShortBuffer() một lần để tạo dữ liệu của mình dưới dạng quần short và đọc từ ShortBuffer đó sau mỗi lần nạp lại ByteBuffer.
Vì vậy, mã trông như thế này:
Ổ cắm DatagramSocket = DatagramChannel.socket();
// code kết nối socket
Kênh DatagramChannel = socket.getChannel();
Bộ đệm ByteBuffer = ByteBuffer.allocateDirect (10000);
// bạn có thể muốn gọi buffer.order(...) ở đây để cho nó biết thứ tự byte nào sẽ được sử dụng
ShortBuffer shortBuf = buffer.asShortBuffer();
// trong vòng nhận của bạn:
đệm.clear();
kênh.receive (bộ đệm);
shortBuf.position(0).limit(buffer.position()/2); // có thể bỏ qua một byte nếu nhận được số lẻ
shortBuf.get(soundBuf,0,shortBuf.limit());
Bạn sẽ thấy mã này hiệu quả hơn mã trước đó vì nó tránh được bản sao hoàn chỉnh của dữ liệu và việc chuyển đổi định dạng được xử lý bằng mã được tối ưu hóa bằng tay thay vì bằng các thao tác byte do trình biên dịch tạo ra, điều này có thể không tối ưu. Sẽ hiệu quả hơn nếu bạn sử dụng thứ tự byte gốc của nền tảng (tôi tin rằng Android sử dụng ít endian trên tất cả các nền tảng có sẵn và mã của bạn ở trên dường như là big endian, vì vậy điều này có thể không thực hiện được (đối với bạn), trong trường hợp đó là shortBuf .get() trở thành bản sao bộ nhớ trực tiếp.
Giới thiệu về java - Các lớp Java ByteBuffer/IntBuffer/ShortBuffer có nhanh không? , chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/4037851/
Tôi có một byteBuffer trống được phân bổ dưới dạng data = ByteBuffer.allocateDirect(layerSize(0, Faces - 1, 0,levels - 1) * laye
Mặc dù phương thức ByteBuffer.put(ByteBuffer) tồn tại nhưng ByteBuffer.get(ByteBuffer) dường như bị thiếu? Tôi nên đọc Byt nhỏ hơn từ ByteBuffer lớn hơn như thế nào
Tôi đang tải tệp nhị phân trong ứng dụng web Dart chứa dữ liệu âm thanh nén như một phần của dữ liệu nhị phân. Khi dữ liệu được tải qua yêu cầu http, nó sẽ xuất hiện dưới dạng ByteBuffer, mà tôi hiểu là câu trả lời của Dart cho JS
Giả sử tôi có một danh sách/danh sách mảng hoặc mảng bộ đệm byte (Danh sách hoặc ByteBuffer []), liệu có thể lấy byte từ mảng trên trực tiếp từ mảng này mà không cần lặp qua tất cả các mục hoặc tính tổng kích thước của chúng không? Tôi đang tìm kiếm thứ gì đó như thế này: ByteBuff
Tôi có một hoặc nhiều ByteBuffer chứa các phần của tin nhắn. Bây giờ tôi muốn đọc tin nhắn này nhưng tôi không muốn sao chép N ByteBuffer vào một tin nhắn. Trình phân tích cú pháp của tôi yêu cầu ByteBuffer chứa thông báo hoàn chỉnh, nhưng
Điều gì sẽ xảy ra nếu nó được biết đến là một bộ đệm khác? Tôi biết điều này có thể được thực hiện với ByteBuffer được hỗ trợ mảng không trực tiếp bằng cách sử dụng phương thức arrayOffset() như thế này: int getRelativeBufferOffset(By
Làm cách nào để sao chép nhanh chóng các byte của ByteBuffer sang một ByteBuffer lớn hơn khác (với độ lệch khác 0) trong Dart? Có nhiều cách chậm để làm điều này. Một là chuyển đổi từng cái thành Uint8List và sao chép nó trong một lần
Này, ByteBuffers và ByteBuff của netty sử dụng các chỉ mục để lưu trữ "vị trí" hiện tại của chúng. Khi bắt đầu ứng dụng, tôi tải nhiều tệp trong ByteBuffers/ByteBuffs để
Tôi biết rằng flip() đặt vị trí bộ đệm hiện tại thành 0 và đặt giới hạn cho vị trí bộ đệm trước đó, trong khi tua lại() chỉ đặt vị trí bộ đệm hiện tại thành 0. Trong đoạn mã bên dưới, tôi sử dụng rewind() hoặc flip() để lấy
Tôi có một mảng ByteBuffer s (thực sự biểu thị các số nguyên). Tôi muốn tách ByteBuffers duy nhất và không duy nhất (tức là số nguyên) trong một mảng. Vì vậy tôi sử dụng loại HashSet này: HashSet columnsSet
Tôi có java.nio.ByteBuffer trong mã của mình: ByteBuffer bb = ByteBuffer.allocateDirect(1024); ... Tôi muốn có thể thay thế nó bằng ByteBu
Tôi cần chuyển mã từ Java sang C#. Trong mã Java, các phương thức "ByteBuffer.flip()" và "ByteBuffer.slice" được sử dụng nhưng tôi không biết cách dịch chúng. Tôi đã đọc câu hỏi này (Một câu hỏi tương đương
Mã Java sau đây biên dịch nhưng báo lỗi khi chạy: # javac ByteBufTest.java # java ByteBufTest Ngoại lệ trong luồng "main" java
Tôi có một phương thức như sau đã hoạt động tốt trong một thời gian dài: Private String LoadFromFile(){ RandomAccessFile inFile = null;
Người dùng đã gặp phải sự cố này trong quá trình thử nghiệm. Suy đoán đầu tiên của tôi là điều này liên quan đến trí nhớ, nhưng tôi không thể làm được gì nhiều ngoài điều đó. Tìm hiểu sâu hơn về mã, tôi nghĩ đây có thể là sự cố của luồng chính, nhưng có vẻ như trình nghe đang bị xóa trên luồng nền, vì vậy tôi nghi ngờ đó là nguyên nhân. Tôi nghĩ trong ứng dụng
Mã sau đây (đây là phiên bản đơn giản) được sử dụng để chạy tốt trong jdk1.6, nhưng hiện tại xác nhận không thành công theo jdk 1.7. Bộ đệm ByteBuffer = ...; buffer.mark(); char c = (char) b
Tôi có tệp nhị phân 10 MB. Tôi cần đọc nó theo khối có kích thước khác nhau (ví dụ: 300, 273 byte). Để đọc, tôi sử dụng FileChannel và ByteBuffer. Bây giờ, với mỗi lần đọc lặp lại, tôi làm
Những gì tôi muốn làm là lấy một số nguyên thập phân, chuyển đổi nó thành thập lục phân và sau đó tách các byte. Theo những gì tôi hiểu, ByteBuffer là cách tốt nhất để đạt được điều này. Số nguyên không thể vượt quá 65535, vì vậy số hex được đảm bảo là 2 byte. Ví dụ: tôi có số nguyên 4
Tôi đang viết một số nội dung sử dụng ByteBuffers. Trong tài liệu của API có ghi Không có cách nào để giải phóng bộ đệm một cách rõ ràng (không có JV
Tôi đang cố đọc một mảng ngắn, chuyển đổi các phần tử của nó và đặt chúng thành một mảng byte. Tôi sử dụng ByteBuffer và nhận được ngoại lệ này: Ngoại lệ trong chuỗi "chính" java.lang.IndexOutOfBoundsExceptio
Tôi là một lập trình viên xuất sắc, rất giỏi!