2016-08-26 8 views
0

Я пытаюсь создать небольшой клиент bittorrent для хранения данных в bittorrent dht. Поскольку большая часть функциональности bittorrent не нужна, я стараюсь оставаться максимально простой, так как она должна функционировать только в нескольких ограниченных случаях использования.Parse 6-байтовый IP/порт для строки in_addr в c

Я пытаюсь разобрать информацию о новых узлах из сообщения, которое я получаю из узла начальной загрузки. Информация о каждом узле имеет длину 26 байтов. 20-байтный идентификатор узла, 4-байтовый IP-адрес и 2-байтовый номер порта. Вся информация находится в двоичном формате. Я хочу сохранить ip-адрес и номер порта в struct (myNode), у которого есть параметр in_addr для IP-адреса и невыполненный короткий для порта.

typedef struct myNode { 
    unsigned char id[21]; 
    struct in_addr ip; 
    unsigned short port; 
} myNode; 

Анализ синтаксического разбора работает отлично. Но синтаксический разбор IP и порта терпит неудачу. Иногда это работает, в основном это не так и никогда не работает одновременно. Я думаю, что может быть что-то не так с побитовым сдвигом, который я делаю, но я не знаю, что. Когда я PRINTF на IP в шестнадцатеричном после разбора я главным образом получить что-то вроде этого:

0xffffed3a

Так кажется, что первые сдвигам не работают. Другие биты верны. Что я делаю не так?

int get_nodes_from_find_node(char *msg, myNode *setme) { 
    char *fnstr = "nodes"; 
    char *pos, *ptr; 
    long lenNodes; 
    int nrNodes, i = 0, k = 0; 

    pos = strstr(msg, fnstr);   // Find nodes section. 
    if(pos == NULL) { return -1; } 
    pos += strlen(fnstr); 

    lenNodes = strtoul(pos, &ptr, 10); // Save the length of the nodes section in lenNodes 
    nrNodes = lenNodes/26;   // Get number of nodes, about which info is delivered. 
    pos = ptr+1;      // Set pos to first node. 

    while(nrNodes > 0) { 
    for(k=0;k<20;k++,pos++) {  // First 20 bytes are ID. 
     setme[i].id[k] = *pos; 
    } 
    setme[i].id[20] = '\0';   // Make ID a Null-terminated string. 

    setme[i].ip.s_addr = (*pos << 24) | (*(pos+1) << 16) | (*(pos+2) << 8) | *(pos+3); // Next 4 bytes are IP in network byte order. 
    pos += 4; 

    setme[i].port = (*pos << 8) | *(pos+1); // Last 2 bytes are port. 
    pos += 2; 

    nrNodes--; 
    i++; 
    }  
    return 0; 
} 
+0

Извините, я не понимаю. Что вы имеете в виду, если вы не привязаны к 4 байтам? – redleo85

ответ

0

Ваша проблема в (*pos << 24) | (*(pos+1) << 16) | (*(pos+2) << 8) | *(pos+3).

Если какое-либо из значений в pos[0,...,3] отрицательно, то все выражение отрицательное.

+0

Это имеет смысл. Как я могу это исправить? – redleo85

+0

Спасибо, что работает сейчас. Нужно было добавить оператора и оператора на каждый бит. Сейчас выглядит немного грязно, но делает работу. :-) ((* pos << 24) & 0xff000000) | ((* (pos + 1) << 16) & 0x00ff0000) | ((* (pos + 2) << 8) & 0x0000ff00) | (* (поз + 3) & 0x000000ff); – redleo85

+0

@ redleo85: Да, вам в основном нужно отбросить каждое из этих терминов до 'unsigned' до OR-ing. –