UDP를 통해 데이터를 전송해야 하는 경우 한계에 직면하게 됩니다. 데이터는 MTU에 맞게 작은 덩어리로 전송되어야 하며, 패킷은 알림 없이 손실되거나 중복되거나 잘못된 순서로 전송될 수 있습니다.
uTP(마이크로 전송 프로토콜)는 UDP를 통해 파일을 안전하게 전송하기 위해 토렌트 사용자가 개발했습니다. 기본적으로 UDP에 TCP 기능을 추가합니다. 손실된 패킷은 자동으로 재전송되고 순서는 보장되며 중복은 거부됩니다.
이 라이브러리는 UDP를 통한 uTP를 구현하므로 연결되면 Node.js tcp 소켓과 매우 유사하게 동작하는 소켓 객체를 받게 됩니다. 데이터를 수신할 때 '데이터'를 내보내며, 버퍼를 보낼 수 있는 .write() 메서드가 있습니다. TCP 소켓과 마찬가지로 이는 Node.js 스트림입니다.
그러나 라이브러리는 다음 기능을 추가하므로 다른 uTP 구현과 호환되지 않을 수 있습니다(따라서 두 피어 모두에서 동일한 라이브러리를 사용해야 함). 클래스의 동일한 인스턴스를 서버와 서버로 모두 사용할 수 있습니다. 동일한 포트에서 동시에 클라이언트. 따라서 노드를 생성하고 이를 포트에 바인딩하는 동시에 들어오는 연결을 수신하고 나가는 연결도 만들 수 있습니다.
npm install --save utp-punch
const Node = require('utp-punch');
let server = new Node(socket => {
console.log('server: socket connected');
socket.on('data', data => {
console.log(`server: received '${data.toString()}'`);
socket.write('world');
socket.end();
});
socket.on('end', () => {
console.log('server: socket disconnected');
server.close(); // this is how you terminate node
});
});
server.bind(20000, '127.0.0.1'); // bind to port 20000
server.listen( // run
() => console.log('server: ready')
);
let client = new Node();
client.bind(); // bind to any port
client.connect(20000, '127.0.0.1', socket => {
console.log('client: socket connected');
socket.on('data', data => console.log(`client: received '${data.toString()}'`));
socket.on('end', () => {
console.log('client: socket disconnected');
client.close(); // this is how you terminate node
});
socket.write('hello');
});
여기서 사용되는 또 다른 기술은 UDP 홀 펀칭입니다.
서버 및/또는 클라이언트가 NAT 뒤에 있는 경우 일반적으로 들어오는 연결을 수신하기 위해 바인딩할 인터넷 IP 주소가 없습니다.
UDP 홀 펀칭은 방화벽을 속여 사용자를 위해 임시 구멍을 열어 NAT 장치의 포트가 LAN 내부의 서버/클라이언트 포트에 바인딩되도록 합니다.
이것이 작동하려면 서버와 클라이언트 모두 타사 서버를 사용하여 서로의 NAT IP 주소를 찾고 펀칭 시도를 조정해야 합니다(서버와 클라이언트에서 동시에 수행되어야 함).
그러나 연결이 설정되면 타사 서버는 더 이상 필요하지 않으며 릴레이로 사용되지 않으며 모든 데이터는 NAT 서버와 클라이언트 간에 직접 전송됩니다.
const Node = require('utp-punch');
let server = new Node();
server.bind(20000);
let client = new Node();
client.bind(30000); // client needs dedicated port
// just as the server
// both server and client must contact a third party server
// which will report their peer NATed address and port to them
let serverAddress, serverPort;
let clientAddress, clientPort;
// up to ten punches:
server.punch(10, clientPort, clientAddress, success => {
// if success is true hole is punched from our side
// nothing to do here as the client will try
// to connect normally when he is also successful
});
client.punch(10, serverPort, serverAddress, success => {
if (success) {
client.connect(serverPort, serverAddress, socket => {
// if the server had also been successful in punching
// this will succeed
});
client.on('timeout', () => {
// if the server had failed in punching we won't be
// able to connect
});
}
});
example/ 디렉토리에서 전체 홀 펀칭 예제를 참조하세요.
동일한 클래스를 서버나 클라이언트로 사용할 수 있으며 구문은 다음과 같습니다.
옵션은 다음과 같습니다:
{
bufferSize: 64, // number of packets
mtu: 1000, // bytes excluding uTP header
timeout: 5000, // ms
resend: 100, // ms
keepAlive: 1000, // ms
}
onConnection에는 단일 인수인 소켓이 전달됩니다. 이것은 서버의 들어오는 연결입니다
노드가 처리할 수 있는 최대 연결 수에 대한 게터
들어오는 연결 수에 대한 게터
나가는 연결 수에 대한 게터
내부적으로 사용되는 표준 Node.js UDP 소켓을 반환합니다.
소켓의 바운드 주소(Node.js UDP .address()와 동일)
호스트:포트에 바인딩하고 완료되면 onBound를 실행합니다.
호스트:포트에 대한 펀칭 시도를 시작하고 성공하거나 시도가 남지 않으면 콜백을 실행합니다. 성공 또는 실패는 첫 번째 부울 매개변수로 콜백에 전달됩니다.
이 노드를 서버로 전환하고 들어오는 연결을 수락할 준비가 되면 이 콜백을 실행합니다.
호스트:포트의 서버 노드에 연결하고 소켓 객체를 단일 매개변수로 사용하여 콜백을 실행합니다.
모든 연결과 노드를 종료하고 콜백을 실행합니다.
Node 생성자와 .connect() 콜백에 전달된 소켓 객체는 데이터를 수신할 때 '데이터'를 방출하는 스트림입니다. .write(), .end() 등의 일반적인 메서드가 있습니다.
원본 'utp' 라이브러리는 https://github.com/mafintosh/utp에서 @mafintosh에 의해 생성되었습니다. 이는 버그 수정과 동일한 포트에서 동시에 서버와 클라이언트로 사용 및 UDP 홀 펀칭 지원을 포함한 추가 기능을 갖춘 최신 JavaScript로 다시 작성된 것입니다.