2017-04-23 2 views
-1

Ich mache gerade ein Projekt auf Networking-Spiel, wo ich ein Spiel entwerfen muss, wo maximal 3 Clients eine Verbindung zum Server herstellen können und das Spiel zwischen allen Clients und Server gespielt wird. Ich benutze die "sockaddr_in" Struktur sowohl auf der Server- als auch auf der Client-Seite.gethostbyname() Alternativen in c

In meinem Spiel kann jeder zum Server werden und die Clients sollten die richtige IP-Adresse und Portnummer angeben, um eine Verbindung zum Server herstellen zu können. Wenn ich die Werte der IP-Adresse des Servers und der Portnummer in "server_address.sin_addr.s_addr" bzw. "server_address.sin_port" fest codiere, funktioniert das Spiel gut. Aber hart codiert löst mein Problem, dass jemand ein Server ist, nicht und fordert die Clients auf, die Adresse und Portnummer des Servers einzugeben. Also habe ich den Funktionsaufruf "gethostbyname()" auf der Clientseite verwendet. Aber es hat mein Problem nicht gelöst. (So ​​kann der Grund dafür ist, dass das Verhalten von gethostbyname() übergibt, wenn eine Ziffernfolge nicht spezifiziert ist (Quelle:.. link)

Im Folgenden wird der Code auf Server-Seite von mir verwendet:

struct sockaddr_in serv_addr, client_addr; 
/* open a socket */ 
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
    { 
     err_ret = errno; 
     return err_ret; 
    } 
    /* set initial values */ 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_port = htons(PORT); 
    serv_addr.sin_addr.s_addr = inet_addr(IP); 
    memset(&(serv_addr.sin_zero), 0, 8); 
    /* bind address with socket */ 
    if(bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) 
    { 
     err_ret = errno; 
     return err_ret; 
    } 

und Client

Seite
struct sockaddr_in serv_addr; 
struct hostent *to; 
/* generate address */ 
if((to = gethostbyname(IP))==NULL) 
{ 
    err_ret = h_errno; 
    fprintf(stderr, "gethostbyname() error...\n"); 
    return err_ret; 
} 
/* open a socket */ 
if((newfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
{ 
    err_ret = errno; 
    fprintf(stderr, "socket() error...\n"); 
    return err_ret; 
} 
/* set initial values */ 
serv_addr.sin_family = AF_INET; 
serv_addr.sin_port = htons(PORT); 
memcpy(&serv_addr.sin_addr, to->h_addr_list[0], to->h_length); 
memset(&(serv_addr.sin_zero), 0, 8); 

Kann jemand hier eine effiziente Art und Weise sagen zu dem oben beschriebenen Prozess durchführt?

Jede mögliche Hilfe würde geschätzt.

+0

Ist Ihr Problem, dass 'gethostbyname (IP)' für eine korrekte numerische Adressfolge fehlschlägt? Oder stellen Sie sich die Frage, wie Sie einen Host dynamisch als Server konfigurieren und seine IP-Adresse potenziellen Kunden bekannt machen? –

+0

Mein Problem ist das erste, das Sie erwähnt haben. Auch die Lösung des zweiten Problems kann mir helfen, das Spiel zu verbessern. Kannst du einen Hinweis auf das Gleiche geben? – likecs

+0

Was beinhaltet 'IP'? Was gibt 'gethostbyname (IP)' zurück? Wie löst es Ihr Problem nicht? Beachten Sie, dass ein Fehlerstatus in 'h_errno' geschrieben wird, nicht in' errno'. –

Antwort

0

getaddrinfo hat gethostbyname abgelöst. Das sollte das Erstellen von Sockaddr_in-Strukturen aus IP-Adress-Strings erleichtern.

Beispielcode, um entweder eine Zeichenfolge in numerischer Form oder als einen Hostnamen in eine Sockaddr_in zu konvertieren.

struct addrinfo hints = {}; 
addrinfo* pResultList = NULL; 
struct sockaddr_in addr = {}; 
char* hostname = "1.2.3.4"; 

hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 
// hints.ai_flags = AI_NUMERICHOST; // if you know hostname is a numeric stirng, you can skip the DNS lookup by setting this flag 

result = getaddrinfo(hostname , NULL, &hints, &pResultList); 

if (result) 
    memcpy(&addr, pResultList->ai_addr, sizeof(addr)); 

if (pResultList != NULL) 
{ 
    ::freeaddrinfo(pResultList); 
} 
+0

Jemand wurde abgelehnt. Nicht sicher warum. Vielleicht würde er gerne etwas dazu sagen, was ihm an der Antwort nicht gefiel? – selbie

+0

Wahrscheinlich weil 'inet_ntoa' veraltet ist und seit einiger Zeit existiert. 'getaddrinfo' ist, was Sie verwenden sollten, nicht diese antiquierten Funktionen. –

+0

@BoundaryImposition - das ist ein ziemlich lahmer Grund zum Downvote, da ich ursprünglich sowohl inet_pton als auch inet_aton zitiert habe. inet_pton ist nicht immer auf allen Plattformen verfügbar. Auf jeden Fall hatte ich beschlossen, meine Antwort zu aktualisieren, um das OP auf "getaddrinfo" zu beschränken. Vielleicht überdenkst du deine Stimme. – selbie