MasterServer Abfrage
-
Nabend,
Ich möchte gerne eine Server liste von dem Valve Master Server abrufen, dazu habe ich mir das c-worker.ch Tutorial durchgelesen und die Doks angeschaut:
http://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol
Hier mein Code:#include <iostream> #include <windows.h> using namespace std; long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr) { long rc; unsigned long ip; HOSTENT* he; if(hostnameOrIp==NULL || addr==NULL) return SOCKET_ERROR; ip=inet_addr(hostnameOrIp); if(ip!=INADDR_NONE) { addr->sin_addr.s_addr=ip; return 0; } else { he=gethostbyname(hostnameOrIp); if(he==NULL) { return SOCKET_ERROR; } else { memcpy(&(addr->sin_addr),he->h_addr_list[0],4); } return 0; } } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); } int main() { long rc; SOCKET s; rc=startWinsock(); SOCKADDR_IN addr; char buf[256]; char buf2[4096]; memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(27011); rc=getAddrFromString("hl2master.steampowered.com",&addr); if(rc==SOCKET_ERROR) { return 1; } else { printf("IP aufgeloest!\n"); } s=socket(AF_INET,SOCK_DGRAM,0); if(s==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if(rc==SOCKET_ERROR) { printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError()); return 1; } buf[0] = 0x31; buf[1] = 0x03; strcat(buf,"0.0.0.0:0"); int i = std::strlen(buf); buf[i+1] = 0x00; buf[i+2] = 0x00; rc=send(s,buf,strlen(buf),0); rc=recv(s,buf2,4096,0); printf("%d",buf2); return 0; }
Ich bekomme aber das hier zurück:
f ┘Ôiç┘µ├.iê┘ð÷8iç┘Þ7Ïiç┘ðÓÏiÁ┘ÞAúiç┘ÃÈNi═┘Ù▲↔iç┘ÃÈNi─┘ý┼¶iç┘ÃÈNi├┘Ýp7iç┘ÃÈNi╣┘ÃÈN i»♦Oæäiç♦Oæºi☻yñiç┘ÃÈHi♠☻♂iç┘ÃÈHi♠☼─iç┘ÃÈHi♠J─iç┘ÃÈHi♠Ksiç┘ÃÈHi♠Lóiç┘ÃÈHi♠┴;iç┘à ÈHi♠┴tiç┘ÃÈ i Aiç┘ÃÈ ☼╦iç┘ÃÈ i ►╣iç┘ÃÈ i ◄§iç┘ÃÈ i ▼ı♀¶5iç┘ÃÈ iî┘ÃÈ iï↑♣í-iç┘ÃÈ iè┘ÃÈ ië↑.¨`iç┘ÃÈ iê┘ÃÈ iç↑ä/╩iç┘Ãi╝↑äûÇiç┘Ãi╣&iPKiç┘Ãi£┘Ãiø┘Ãiê┘Ãiç┘─P½iû┘─P½iî:♥x¬iç┘─P¬i╚:←╚wiç┘─P¬i¥ ië┘«¹6iç>♦G‼iç┘«·¶iç>♦JFiç┘¡á7qW>♦JFiÑ>♦JFi╣┘¡*Çiï>♦JFi├┘¡*Çiè>♦JFi═┘¡*Çië>♦JFiÎ ┘¡*Çiç>♦JGiÎ┘¡*Çiä>♦JGiß┘¡*$m`>♦JHiç┘¡*$oT>♦JJiæ┘¼╝Óiè>♦JJi═┘¼╝Óië>♦Jëy↑┘¼╝Óiê>♦ Jòu0┘¼╝Ziç>♦J¢y↑┘¼╝):¿>♦J¢v\┘¼╗.iç>♦J¢uö┘¼Âciç>♦J¢v└┘¼┤‗i▄┘¼┤‗iç>♦J┐v└┘¼┤⌂iç>♦Jã u0┘¼┤%mo>♦J¦uö┘¼▓▀i▄>♦JÚv\┘¼▓fiæ>♦Jýu0┘¼▓fiç>♦J‗u°┘¼▓∟iû>♦J§u°>♦J÷x┤┘¼0─iç>♦J¨{♀ ┘¼!6a¿>♦J¨|8>♦J¨{p┘¼!6qH>♦J·w$┘¼!6u0>♦QÕu0>♦QÕuö┘¼▬☼iç>♦Qþu0┘¬§§iç>♦Qþv\┘®Ôv·³>♦ Qþv└┘®Ôv§├>♦QÚv\┘®Ôv·¥>♦QÚiç┘®Ôv╦J>♦QÛv\>♦QÛu°┘¿Ö²iè>♦Qýv\┘¿Ö²ië>♦Q{♀┘¿Ö²iê>♦Q |8┘¿Ö²iç>♦Q{p┘¿Ö²iå>♦Q|£┘¿û▀iç>♦Qx┤┘ú▼µiç>♦Qv└>♦Q{È┘ú▼Ìiç>♦Qwý┘ú▼┘iç>♦Q¶w$ ┘ú▼Îiç>♦Q¶v\>♦Q¶uö┘ú▼Íiç>♦Q¶v└┘ú▼¤iç>♦Q¨u0┘ú▼═iç>♦Q·wê┘ú▼║iç>♦Q¹v\┘ú▼©iç┘ú▼│iç>♦ Q³z¿>♦Y▼w$┘ú▼▓içd²içd²iê┘ú▼¼içd²iø┘ú▼¬içd²iÑ┘ú▼ªid²i├┘ú▼Ñiç>►Ùäiç>►´¥iç┘ú▼xiç>§b rià>↑Dþiç┘ú▼wiç>↑Dþiê>↑DÞiç┘ú▼uiç>←,ñiç┘ú▼tiç┘ú▼siç>↔ániç┘ú▼riç>#sëiç┘ú▼piç>)→ iç>+╝Áiç┘ú▼iiç>/ñ◄΃>/ñ◄ή┘ú▼hiç>/ñ◄ά┘ú▼giç>/ñ◄Î▓>/ñ◄Î│┘ú▼eiç>/ñ◄Î¥┘ú▼diç>/ñ◄Î┐ ┘ú▼<iç>0JÈiç³
Da steht das der Server in bytes die ips zurückgibt nur wie kann ich die da raus ziehen?
-
Mit der Funktion man: ntohl(3) wandelst du die Daten in Host-Byteorder um und mit man: inet_ntoa die Daten dann in eine IP-Adresse.
-
Hi,
Danke für deine Antwort.
Kannst du mir auch sagen wie ich die IP's voneindaner trenne um sie in ntohl zu nutzen?
Wird die ip immer bei ;ÃÈNi& getrennt?
Ich kapier das mit den zeichen nicht wäre irgendwie besser die würden das in klartext übertragen.
-
liest du deinen eigenen link eigentlich nicht
Reply format
The reply always starts with FF FF FF FF 66 0A.
The format is then a series of these server address blocks:
Type Data
Byte First octet of IP address
Byte Second octet of IP address
Byte Third octet of IP address
Byte Fourth octet of IP address
Unsigned Short Port number - usually 27015 (69 87) - this is network ordered, which is unlike every other Steam protocol.
-
Hi,
Schon klar das dass da steht, aber ich bekomme ja kein FF zurück oda so.
Mit der Zeichenkette was ich zurück bekomme kann ich 0 anfangen
-
du bekommst keine zeichenkette zurück, nur wenn du es mit printf ausgibst, ist es wohl klar, daß er schrott anzeigt, wenn er irgendwelche ip addressen schickt.
hier
int main() { SOCKET s; WSADATA wsa; INT rc; CHAR buffer[4096] ={0}; SOCKADDR_IN addr = {0}; WSAStartup(MAKEWORD(2,0), &wsa); addr.sin_family = AF_INET; addr.sin_port = htons(27011); getAddrFromString("hl2master.steampowered.com",&addr); s = socket(AF_INET, SOCK_DGRAM, 0); rc = connect(s, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)); if( rc == SOCKET_ERROR ) { printf("Fehler: connect, fehler code: %d\n",WSAGetLastError()); return 1; } const char cmd[] = { 0x31, 0x03, '0', '.', '0', '.', '0', '.', '0', ':', '0', 0x00 }; rc = send(s, cmd, 12, 0); if( rc == SOCKET_ERROR ) { printf("Fehler: send, fehler code: %d\n",WSAGetLastError()); return 1; } rc = recv(s, buffer, 4096, 0); if( rc == SOCKET_ERROR ) { printf("Fehler: recv, fehler code: %d\n",WSAGetLastError()); return 1; } const unsigned char reply_magic[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x0A }; if(memcmp(buffer, reply_magic, sizeof(reply_magic))) { printf("fehlerhafte antwort\n"); return 1; } int offset = sizeof(reply_magic); int cnt = 0; while(1) { printf("%u.%u.%u.%u:%d\n", (unsigned char)buffer[offset + 0], (unsigned char)buffer[offset + 1], (unsigned char)buffer[offset + 2], (unsigned char)buffer[offset + 3], (unsigned short*)((buffer[offset + 4] << 8) | (buffer[offset + 5] & 0xFF))); if( (unsigned long*)buffer[offset] == 0x00000000 ) { printf("end of list reached\n"); break; } offset += 6; } return 0; }
-
Hi,
Funktioniert nun so, aber mich Interessiert auch was da genau passiert. Da ich noch recht neu bin in C++ hab ich nicht alles verstanden.Also:
In Line 39 wird Überprüft ob der Header vom Server richtig ist und falls nicht wird abgrbochen.
Dannach wird der Offset auf die Größe des Headers gesetzt damit man auf die ips zugreifen kann.
Nur was beudeutet bie der Port nummer:(unsigned short*)((buffer[offset + 4] << 8) | (buffer[offset + 5] & 0xFF))
Das verstehe ich nicht!
und auch bei der Überprüfung ob man am ende istif( (unsigned long*)buffer[offset] == 0x00000000 )
Warum diese vielen nullen und nicht einfach eine null?