实现思路
- 确认机制:发送方发送数据后,等待接收方返回确认消息(ACK)。若在规定时间内收到ACK,表明数据成功接收;否则,认为数据丢失。
- 重传机制:若发送方在超时时间内未收到ACK,重新发送数据。可设置最大重传次数,避免无限重传。
- 序列号:为每个发送的数据段添加序列号,接收方根据序列号对数据进行排序,确保数据按顺序处理。
关键代码片段
- 发送方代码
const net = require('net');
const socket = new net.Socket();
const serverAddress = '127.0.0.1';
const serverPort = 8080;
const maxRetries = 3;
const timeout = 1000; // 1秒超时
let sequenceNumber = 0;
let retries = 0;
let timer;
function sendData(data) {
const packet = {
seq: sequenceNumber++,
data: data
};
socket.write(JSON.stringify(packet));
startRetransmissionTimer();
}
function startRetransmissionTimer() {
timer = setTimeout(() => {
if (retries < maxRetries) {
console.log('未收到ACK,重传数据');
sendData(currentData);
retries++;
} else {
console.log('达到最大重传次数,放弃重传');
}
}, timeout);
}
function clearRetransmissionTimer() {
clearTimeout(timer);
retries = 0;
}
socket.connect(serverPort, serverAddress, () => {
const currentData = 'Hello, Server!';
sendData(currentData);
});
socket.on('data', (data) => {
const response = JSON.parse(data.toString());
if (response.type === 'ACK' && response.seq === sequenceNumber - 1) {
console.log('收到ACK,数据传输成功');
clearRetransmissionTimer();
}
});
socket.on('error', (err) => {
console.error('Socket error:', err);
});
socket.on('close', () => {
console.log('Socket closed');
});
- 接收方代码
const net = require('net');
const server = net.createServer((socket) => {
const receivedPackets = [];
socket.on('data', (data) => {
const packet = JSON.parse(data.toString());
receivedPackets.push(packet);
receivedPackets.sort((a, b) => a.seq - b.seq);
// 处理按序到达的数据
let expectedSeq = 0;
while (receivedPackets.length > 0 && receivedPackets[0].seq === expectedSeq) {
const processedPacket = receivedPackets.shift();
console.log('处理数据:', processedPacket.data);
expectedSeq++;
}
// 发送ACK
const ack = {
type: 'ACK',
seq: packet.seq
};
socket.write(JSON.stringify(ack));
});
socket.on('error', (err) => {
console.error('Socket error:', err);
});
socket.on('close', () => {
console.log('Socket closed');
});
});
const port = 8080;
server.listen(port, () => {
console.log(`Server listening on port ${port}`);
});