使用 `ByteBuffer` 發送圖片對象,接收端數據不完整、圖片損壞、丟失大量數據。
ByteBuffer 讀寫模式切換(flip/rewind/compact)使用不當,導致:
ByteBuffer buffer = ByteBuffer.allocate(1024 * 64); // 64KB
// 1. 序列化圖片到 buffer(put 操作)
buffer.put(imageBytes); // position 推進
// 2. **關鍵:翻轉準備讀取/發送**
buffer.flip(); // limit=position, position=0
// 3. 循環發送直到 buffer 無剩餘
while (buffer.hasRemaining()) {
int written = channel.write(buffer);
if (written == 0) {
// 可選:等待可寫事件(Selector OP_WRITE)
}
}
ByteBuffer buffer = ByteBuffer.allocate(1024 * 64);
// 1. 讀取長度前綴(假設協議:前4字節為圖片長度)
ByteBuffer header = ByteBuffer.allocate(4);
while (header.hasRemaining()) channel.read(header);
header.flip();
int length = header.getInt();
// 2. 分配精確大小 buffer
ByteBuffer body = ByteBuffer.allocate(length);
// 3. 循環讀取直到填滿
while (body.hasRemaining()) {
int read = channel.read(body);
if (read == -1) throw new EOFException("連接斷開");
}
body.flip(); // 準備讀取數據
byte[] imageData = new byte[length];
body.get(imageData); // 完整圖片數據
| 方法 | 作用 | 位置變化 |
|---|---|---|
| put() | 寫入數據 | position += n |
| flip() | 切換為讀模式 | limit=position, position=0 |
| rewind() | 重讀(不改limit) | position=0 |
| compact() | 未讀數據移至開頭 | 未讀數據前移, position=剩餘 |
| clear() | 重置寫模式 | position=0, limit=capacity |
| hasRemaining() | 是否有剩餘可讀/寫 | position < limit |