2016-12-28 3 views
4

내가 Node.js를 사용하여 비트 토 런트 클라이언트를 구축하고있어 (BEP 0009)ut_metadata 조각 요청에 대한 응답을 얻으려면 어떻게해야합니까? (Node.js를 비트 토런트 BEP 0009)

내가 DHT에서 동료를 얻을 PWP 메타 데이터 확장을 통해 동료들로부터 답을 얻기에 실패하고 (BEP 0005) (내가 발표 한 곳), 그물 소켓을 사용하여 PWP를 통해 핸드 셰이크 및 확장 핸드 셰이크를 보냅니다. 여기에서

buildHandshake = (torrent, ext) => { // torrent contains mainly infoHash 
    const buf = Buffer.alloc(68) 
    buf.writeUInt8(19, 0) 
    buf.write('BitTorrent protocol', 1) 
    if (ext) { 
     const big = new Uint64BE(1048576) 
     big.toBuffer().copy(buf, 20) 
    } else { 
     buf.writeUInt32BE(0, 20) 
     buf.writeUInt32BE(0, 24) 
    } 
    torrent.infoHashBuffer.copy(buf, 28) 
    anon.nodeId().copy(buf, 48) // tool that generates a nodeId once. 
    return buf 
} 

buildExtRequest = (id, msg) => { 
    const size = msg.length + 1 
    const buf = Buffer.alloc(size + 5) 
    buf.writeUInt32BE(size, 0) 
    buf.writeUInt8(20, 4) 
    buf.writeUInt8(id, 5) 
    msg.copy(buf, 6) 
    return buf 
} 

const client = new net.Socket() 
    client.connect(peer.port, peer.ip,() => { 
     client.write(buildHandshake(torrent, true)) 
     const extHandshake = bencode.encode({ 
      m: { 
       ut_metadata: 2, 
      }, 
      metadata_size: self.metaDataSize, // 0 by default 
      p: client.localPort, 
      v: Buffer.from('Hypertube 0.1') 
     }) 
     client.write(buildExtRequest(0, extHandshake)) 
}) 

, 난 악수 및 확장 Hanshakes 다시 (때로는 비트 필드), 그럼 내가 메타 데이터 조각을 필요로 얻을 :

const req = bencode.encode({ msg_type: 0, piece: 0 }) 

// utMetadata is from extended Handshake dictionary m.ut_metadata 
client.write(message.buildExtRequest(utMetadata, req)) 

무엇 후, 난 더 이상 피어에서 소리가 나지 않습니다. 2 분이 지나도 살아 있지 않으면 연결 시간 초과가 발생합니다.

답변을받지 못한 사람이 누구나 있으십니까?

+0

WireShark 그리고 일하는 고객과 비교할 것인가? – Encombe

+0

당신과 그들의 메시지의 hexdump가 도움이 될 것입니다. – the8472

+2

저는 Wireshark에서 작업하여 어디에 문제가 있는지 알았습니다 : 값이 정의되지 않은 경우 bencode.encode는 값없이 키를 인코딩 할 것이고 오류는 던지지 않을 것입니다. 이것은 이상하게도 길이 접두어가 1 바이트 빠져서 다음 메시지가 확장되지 않고 오히려 _interested_ 또는 _unchoke_가 잘못 형성되어 피어가 닫히게되었습니다. –

답변

1

BitTorrent 프로토콜 메시지는 나를 좋아하는 첫 번째 타이머 인 경우 명확하지 않을 수 있습니다.

메시지 구조는 (핸드 셰이크 제외)은 다음과 같이 항상 :

이 값 message.length의 UINT32 큰 엔디안
<len><message> 

, 메시지 당신이 악수를 제외하고 보내는 어떤이다 .

확장 프로토콜 조각 요청 :

  • 를 렌 값의 UINT32 큰 엔디안 :

    <len><id><extId><ut_metadata dict> 
    

    이 ut_metadata 조각 메시지의 크기()

  • exemple 들어

  • ID은 값 20의 Uint8입니다. (프로토콜 확장 표시기입니다)
  • extId은 UInt8입니다.

    { 'msg_type': 0, 'piece': 0 }

    d8:msg_typei0e5:piecei0ee

:이 값은 (ut_metadata 교환 EXTID가 제공하는) 피어
  • ut_metadata의 딕셔너리가 bencoded 사전이다로부터 수신 extended handshake에 따라

    (여기서 첫 줄에 objet - 사전은이고 두 번째 줄에는 같은 obje가 있습니다. 회) bencoded CT

    • MSG_TYPE 0 (이것은 BEP 0009요청에 대한 요청 메시지 지시자이다이다.

    • 조각는 일반적으로

    (0은 최초의 작품이 될 것입니다) 당신이 요청하는 부분의 인덱스 :

    <len>에 대한 권리 값이 심하게 메시지가 발생합니다 포기하지 않을 피어에 의해 해석되어 올바른 대답을 얻지 못해 어떤 대답도 얻지 못하고 결국 동료가 또는 자신의 메시지를 통해 연결이 닫히는 경우