udt nat traverse

https://github.com/bakwc/udt-nat-traverse

Example of nat traversal using udt library. UDT is a udp based connection establishing protocol.

  • server.cpp - waiting for two clients, send them their addresses
  • client.cpp - connects to server, wait for other client address, connects to other client
#include <arpa/inet.h>
#include <udt.h>
#include <iostream>
#include <cstring>

using namespace std;

int main() {
    UDTSOCKET serv = UDT::socket(AF_INET, SOCK_STREAM, 0);

    sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(6890);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    memset(&(my_addr.sin_zero), '\0', 8);

    if (UDT::ERROR == UDT::bind(serv, (sockaddr*)&my_addr, sizeof(my_addr))) {
        cout << "bind error: " << UDT::getlasterror().getErrorMessage();
        return 0;
    }

    UDT::listen(serv, 10);


    while(true) {
        int namelen;
        sockaddr_in recver1addr, recver2addr;
        char ip[16];
        char data[6];
        cout << "waiting for connections\n";

        UDTSOCKET recver1 = UDT::accept(serv, (sockaddr*)&recver1addr, &namelen);
        cout << "new connection: " << inet_ntoa(recver1addr.sin_addr) << ":" << ntohs(recver1addr.sin_port) << endl;

        UDTSOCKET recver2 = UDT::accept(serv, (sockaddr*)&recver2addr, &namelen);
        cout << "new connection: " << inet_ntoa(recver2addr.sin_addr) << ":" << ntohs(recver2addr.sin_port) << endl;

        cout << "sending addresses\n";
        *(uint32_t*)data = recver2addr.sin_addr.s_addr;
        *(uint16_t*)(data + 4) = recver2addr.sin_port;
        UDT::send(recver1, data, 6, 0);


        *(uint32_t*)data = recver1addr.sin_addr.s_addr;
        *(uint16_t*)(data + 4) = recver1addr.sin_port;
        UDT::send(recver2, data, 6, 0);

        UDT::close(recver1);
        UDT::close(recver2);
    }

    UDT::close(serv);

    return 1;
}
#include <iostream>
#include <udt.h>
#include <arpa/inet.h>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <unistd.h>

using namespace std;
using namespace UDT;

int main() {
    UDTSOCKET client = UDT::socket(AF_INET, SOCK_STREAM, 0);

    sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(6890);
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);   // server address here
    memset(&(serv_addr.sin_zero), '\0', 8);

    // selecting random local port
    srand(time(NULL));
    int myPort = 9001 + rand() % 200;
    printf("my port: %d\n", myPort);

    sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(myPort);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    memset(&(my_addr.sin_zero), '\0', 8);


    // Connecting to server

    // binding my port
    if (UDT::ERROR == UDT::bind(client, (sockaddr*)&my_addr, sizeof(my_addr))) {
        cout << "bind error: " << UDT::getlasterror().getErrorMessage();
        return 0;
    }

    // connect to the server
    if (UDT::ERROR == UDT::connect(client, (sockaddr*)&serv_addr, sizeof(serv_addr))) {
        cout << "connect error: " << UDT::getlasterror().getErrorMessage();
        return 42;
    }

    char data[6];
    if (UDT::ERROR == UDT::recv(client, data, 6, 0)) {
        cout << "recv error:" << UDT::getlasterror().getErrorMessage() << endl;
        return 0;
    }

    sockaddr_in peer_addr;
    peer_addr.sin_family = AF_INET;
    peer_addr.sin_addr.s_addr = *(uint32_t*)data;
    peer_addr.sin_port = *(uint16_t*)(data + 4);

    cout << "addr received: " << inet_ntoa(peer_addr.sin_addr) << ":" << ntohs(peer_addr.sin_port) << endl;
    UDT::close(client);

    client = UDT::socket(AF_INET, SOCK_STREAM, 0);
    bool rendezvous = true;
    UDT::setsockopt(client, 0, UDT_RENDEZVOUS, &rendezvous, sizeof(bool));

    if (UDT::ERROR == UDT::bind(client, (sockaddr*)&my_addr, sizeof(my_addr))) {
        cout << "bind error: " << UDT::getlasterror().getErrorMessage();
        return 0;
    }

    if (UDT::ERROR == UDT::connect(client, (sockaddr*)&peer_addr, sizeof(peer_addr))) {
        cout << "connect error: " << UDT::getlasterror().getErrorMessage();
        return 42;
    }
    cout << "SUCCESS!\n";
    sleep(2); // give another client time to connect too

    return 1;
}

 

posted @ 2014-04-30 14:17  IAmAProgrammer  阅读(745)  评论(0编辑  收藏  举报