accept mit AF_INET liefert sockaddr_in-Objekt, dass inet_pton nicht immer lesen kann
-
Hallo, Leute.
Ich habe hier ein merkwürdiges Problem mit einem selbstgeschriebenen TCP-Server unter Linux (Ubuntu/Debian, jeweils Kernel 2.6.32-48/3.7 (selbstkompiliert), jeweils i686/x86_64).Szenario:
Ich erstelle einen AF_INET-Socket für verbindungsbasierte Kommunikation und binde diesen dann an einen Port. Den laufenden Prozess spreche ich dann mit telnet 127.0.0.1 1337 an. Auf meiner Ubuntu-Maschine wird dann immer ausgegeben, dass die Network-Family AF_INET aka 2 ist, auf meiner Debian-Maschine gibt der allererste Connect zum Server allerdings eine Network-Family von 0 an - was er nicht ist. Beim zweiten Connect erhalte ich dann die richtige Family.Aber noch was: auch die Peer-IP ist auf der x86_64-Maschine beim ersten Laden kaputt, nach dem zweiten Laden ist sie korrekt.
Ich habe daher einmal folgendes Szenario durchgeführt:
Code auf einer i686-Maschine kompiliert, laufen lassen.
Code auf einer x64-Maschine kompiliert, laufen lassen.
telnet auf der i686-Maschine aufrufen lassen, auf den x64er connected- hat mir das hier ausgegeben:Attempting to convert address 192.168.0.250, port 1337 ... Bind address 192.168.0.250 successfully converted to network form 4194347200|fa00a8c0 ... Network form of port 1337 is 14597 ... Socket 3 successfully created ... Socket 3 successfully binded ... Socket 3 is listening now ... New incomming request from peer 0|16 ... Peer address is 0.0.0.0 ... # und das ist falsch, sollte 192.168.0.215 sein.
telnet auf der x64-Maschine aufrufen lassen, auf den i686 connected- hat mir das hier ausgegeben:
Attempting to convert address 192.168.0.215, port 1337 ... Bind address 192.168.0.215 successfully converted to network form 3607144640|d700a8c0 ... Network form of port 1337 is 14597 ... Socket 3 successfully created ... Socket 3 successfully binded ... Socket 3 is listening now ... New incomming request from peer 2|16 ... Peer address is 192.168.0.250 ..
Code kompiliert mit g++ -O2 text.cpp -o program
#include <cstdio> #include <cstring> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { int yes=1; char*source="127.0.0.1"; int port=1337; struct sockaddr_in bind_addr; bind_addr.sin_family =AF_INET; bind_addr.sin_port =htons(port); printf("Attempting to convert address %s, port %u ...\n",source,port); if(!inet_pton(AF_INET,source,&bind_addr.sin_addr)) { fprintf(stderr,"Couldn't convert address %s into network address\n",source); return 1; } printf("Bind address %s successfully converted to network form %u|%x ...\n",source,bind_addr.sin_addr,bind_addr.sin_addr); printf("Network form of port %u is %u ...\n",port,htons(port)); int sock=socket(bind_addr.sin_family,SOCK_STREAM,0); if(sock==-1) { printf("%u|%u|%u\n",bind_addr.sin_family,SOCK_STREAM,0); perror("socket"); return 2; } if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1) { perror("setsockopt"); return 3; } printf("Socket %u successfully created ...\n",sock); if(bind(sock,(struct sockaddr*)&bind_addr,sizeof(struct sockaddr_in))==-1) { perror("bind"); return 4; } printf("Socket %u successfully binded ...\n",sock); if(listen(sock,20)==-1) { perror("listen"); return 5; } printf("Socket %u is listening now ...\n",sock); int peer_sock; struct sockaddr_storage peer_addr; struct sockaddr_in*peer_addr_in; socklen_t peer_addr_len; char str[INET6_ADDRSTRLEN]; while(peer_sock=accept(sock,(struct sockaddr*)&peer_addr,&peer_addr_len)) { peer_addr_in=(struct sockaddr_in*)&peer_addr; inet_ntop(bind_addr.sin_family,&peer_addr_in->sin_addr,str,sizeof(*peer_addr_in)); printf("New incomming request from peer %u|%u ...\n",peer_addr.ss_family,peer_addr_len); printf("Peer address is %s ...\n",str); close(peer_sock); } close(sock); return 0; }
Kann mir mal einer verraten, wieso es auf der x64-Maschine nicht tut? Die Ironie ist, ich habe das Ding ursprünglich auf einer x64-Maschine geschieben und durch Zufall rausgefunden, dass es auf der i686-Maschine wunderbar tut.
-
port sollte unsigned short sein!