在Java Socket編程中,粘包問題通常是由于TCP協議是基于流的傳輸方式,而不是基于消息的傳輸方式。因此,當發送多個數據包時,它們可能會被合并成一個數據包,或者在接收端接收到的數據包可能被拆分成多個部分。為了解決這個問題,可以采用以下方法:
// 發送端
public void sendPacket(String data) throws IOException {
byte[] header = new byte[4];
ByteBuffer buffer = ByteBuffer.wrap(header);
buffer.putInt(data.length());
socket.getOutputStream().write(header);
socket.getOutputStream().write(data.getBytes());
}
// 接收端
public String receivePacket() throws IOException {
byte[] buffer = new byte[4];
int length = socket.getInputStream().read(buffer);
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, length);
int dataLength = byteBuffer.getInt();
byte[] data = new byte[dataLength];
socket.getInputStream().read(data);
return new String(data);
}
// 發送端
public void sendPacket(String data) throws IOException {
byte[] separator = new byte[]{0x0A}; // 使用換行符作為分隔符
socket.getOutputStream().write(separator);
socket.getOutputStream().write(data.getBytes());
socket.getOutputStream().write(separator);
}
// 接收端
public String receivePacket() throws IOException {
List<Byte> buffer = new ArrayList<>();
int receivedByte;
while ((receivedByte = socket.getInputStream().read()) != -1) {
buffer.add(receivedByte);
if (buffer.get(buffer.size() - 1) == 0x0A) { // 遇到分隔符
byte[] data = new byte[buffer.size() - 1];
for (int i = 0; i < data.length; i++) {
data[i] = buffer.get(i);
}
return new String(data);
}
}
return "";
}
// 發送端
public void sendPacket(String data) throws IOException {
byte[] header = new byte[8];
ByteBuffer buffer = ByteBuffer.wrap(header);
buffer.putInt(data.length());
buffer.putLong(System.currentTimeMillis()); // 添加時間戳
socket.getOutputStream().write(header);
socket.getOutputStream().write(data.getBytes());
}
// 接收端
public String receivePacket() throws IOException {
byte[] buffer = new byte[8];
int length = socket.getInputStream().read(buffer);
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, length);
int dataLength = byteBuffer.getInt();
long timestamp = byteBuffer.getLong();
byte[] data = new byte[dataLength];
socket.getInputStream().read(data);
return new String(data);
}
這些方法可以有效地解決Java Socket中的粘包問題。在實際應用中,可以根據具體需求選擇合適的方法。