PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » PureBasic для Windows » Запрос к серверу


Запрос к серверу

Сообщений 1 страница 5 из 5

1

Привет всем < 3

Хочу получить список серверов < 3 После моего запроса к серверу, я получил приличный набор символов.
Нашел этот код на С:

Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef WIN32
    #include <winsock.h>
    #include "winerr.h"

    #define    close    closesocket
    #define sleep   Sleep
    #define ONESEC  1000
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <netdb.h>

    #define ONESEC  1
#endif



#define VER     "0.1"
#define BUFFSZ  4096
#define MS      "master.quake3arena.com"
#define MSPORT  27950
#define REQ     "\xff\xff\xff\xff" \
                "getservers 68\n"
#define TIMEOUT 5



int timeout(int sock);
u_int resolv(char *host);
void std_err(void);



int main(int argc, char *argv[]) {
    struct    sockaddr_in     peer;
    int        sd,
            err,
            rlen,
            i,
            tot = 0;
    u_char  *buff,
            *ptr;
    u_int  ip;
    u_short port;

#ifdef WIN32
    WSADATA    wsadata;
    WSAStartup(MAKEWORD(2,0), &wsadata);
#endif
    FILE *file;
    file = fopen("input.txt","w");
    setbuf(stdout, NULL);

    peer.sin_addr.s_addr = resolv(MS);
    peer.sin_port        = htons(MSPORT);
    peer.sin_family      = AF_INET;
    rlen                 = sizeof(peer);

    buff = malloc(BUFFSZ + 1);
    if(!buff) std_err();

    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sd < 0) std_err();

    err = sendto(sd, REQ, sizeof(REQ) - 1, 0, (struct sockaddr *)&peer, rlen);
    if(err < 0) std_err();

    while(1) {
        err = timeout(sd);
        if(err < 0) break;
        err = recvfrom(sd, buff, BUFFSZ, 0, (struct sockaddr *)&peer, &rlen);
        if(err < 0) std_err();
        if(!err) break;

        if(memcmp(buff + 4, "getserversResponse", 18)) break;

        i = 23;             /* 4 (ffffffff) + 18 (get..) + 1 (\) */
        ptr = buff + 23;
        while(i < err) {
            if(!memcmp(ptr, "EOT", 3)) break;
            ip = *(u_int *)ptr;
            port = *(u_short *)(ptr + 4);
            printf("%15s   %hu\n",
                inet_ntoa(*(struct in_addr *)&ip),
                htons(port));
            ptr += 7;
            i += 7;
            tot++;
            fprintf(file,"%15s   %hu\n",
                inet_ntoa(*(struct in_addr *)&ip),
                htons(port));
        }
    }
    fclose(file); /*done!*/ 
    close(sd);

    printf("\nTotal servers found: %d\n\n", tot);

    return(0);
}



int timeout(int sock) {
    struct    timeval    tout;
    fd_set    fd_read;
    int    err;

    tout.tv_sec = TIMEOUT;
    tout.tv_usec = 0;
    FD_ZERO(&fd_read);
    FD_SET(sock, &fd_read);
    err = select(sock + 1, &fd_read, NULL, NULL, &tout);
    if(err < 0) std_err();
    if(!err) return(-1);
    return(0);
}



u_int resolv(char *host) {
    struct        hostent    *hp;
    u_int        host_ip;

    host_ip = inet_addr(host);
    if(host_ip == INADDR_NONE) {
        hp = gethostbyname(host);
        if(!hp) {
            printf("\nError: Unable to resolv hostname (%s)\n", host);
            exit(1);
        } else host_ip = *(u_int *)(hp->h_addr);
    }
    return(host_ip);
}



#ifndef WIN32
    void std_err(void) {
        perror("\nError");
        exit(1);
    }
#endif

Меня интересует этот момент:

Код:
 while(1) {
        err = timeout(sd);
        if(err < 0) break;
        err = recvfrom(sd, buff, BUFFSZ, 0, (struct sockaddr *)&peer, &rlen);
        if(err < 0) std_err();
        if(!err) break;

        if(memcmp(buff + 4, "getserversResponse", 18)) break;

        i = 23;             /* 4 (ffffffff) + 18 (get..) + 1 (\) */
        ptr = buff + 23;
        while(i < err) {
            if(!memcmp(ptr, "EOT", 3)) break;
            ip = *(u_int *)ptr;
            port = *(u_short *)(ptr + 4);
            printf("%15s   %hu\n",
                inet_ntoa(*(struct in_addr *)&ip),
                htons(port));
            ptr += 7;
            i += 7;
            tot++;
            fprintf(file,"%15s   %hu\n",
                inet_ntoa(*(struct in_addr *)&ip),
                htons(port));
        }
    }

Тут идет разбор этих символов на то что нужно (ИП адреса и порты)
Вопрос в том, как сделать этот разбор на Пурике, если ответ от сервера содержится в строке.
Буду очень благодарен за помощь <3 Вы моя единственная надежда < 3

0

2

Не понял проблемы.
Ты не смог восстановить из Си-кода алгоритм разбора результата?

Где-то так.
1. Если в buff с 5-го байта 18 байтов равны "getserversResponse" то прервать разбор.
2. Цикл начиная с 23-го байта
либо 3 байта равны"EOT" тогда конец списка
либо 7 байтов - элемент списка (4 байта = IP, 2 байта = номер порта)

Для извлечения кусочков (фрагментов) строки можно использовать Mid()

Syntax

Result$ = Mid(String$, StartPosition [, Length])
Description

Extract a string of specified 'Length' from the given 'String$'. 'StartPosition' (minimum value = 1) specifies which character position to start extracting from. 'Length' is optional and specifies how many characters from that position you want to extract. If 'Length' is omitted, characters are extracted until the end of string.
Example:

  Debug Mid("Hello", 2) ; Will display "ello"
  Debug Mid("Hello", 2, 1) ; Will display "e"

0

3

ewardd написал(а):

Вопрос в том, как сделать этот разбор на Пурике, если ответ от сервера содержится в строке.

Разве в СИшном коде результат хранится в строке?
В коде работа с памятью и в пурике нужно сделать так же. http://purebasic.ru/manual.php?id=781&lng=rus

0

4

Я с памятью не очень дружу (

Был бы очень благодарен за небольшой пример.

0

5

Код:
InitNetwork() 

Procedure$ GetHTTP(Server$, Page$, Port, Protocol$, BufferSize, Sleep, TimeLimit)
  Protected connection_id.i = OpenNetworkConnection(Server$, Port, #PB_Network_TCP) 
  If connection_id <> 0 
    
    Protected string_to_send.s = "GET /" + Page$ + " " + Protocol$ + #CRLF$ 
    string_to_send + "Host: " + Server$ + #CRLF$ 
    string_to_send + "Connection: Close" + #CRLF$ + #CRLF$ 
    
    SendNetworkString(connection_id , string_to_send) 
    
    Protected time_current.i = ElapsedMilliseconds() 
    Protected time_limit.i = time_current + TimeLimit
    
    Protected final_of_transmission.i = 0 
    
    Repeat      
      Select NetworkClientEvent(connection_id) 
        Case #PB_NetworkEvent_Data 
          Repeat 
            Protected *memory_buffer = AllocateMemory(BufferSize) 
            Protected received_size.i = ReceiveNetworkData(connection_id, *memory_buffer, BufferSize) 
            If received_size = -1 Or received_size = 0 
              FreeMemory(*memory_buffer) 
              final_of_transmission.i = 1 
              Break 
            Else 
              Protected received_size_global.i 
              received_size_global + received_size 
              Protected *memory_global = ReAllocateMemory(*memory_global, received_size_global) 
              CopyMemory(*memory_buffer, *memory_global + (received_size_global - received_size), received_size) 
              FreeMemory(*memory_buffer) 
            EndIf 
          ForEver 
      EndSelect 
      
      If final_of_transmission = 1 
        CloseNetworkConnection(connection_id) 
        
        Protected content.s = PeekS(*memory_global, received_size_global) 
        FreeMemory(*memory_global) 
        
        ProcedureReturn content
        
        Break 
      Else 
        time_current = ElapsedMilliseconds() 
        If time_current > time_limit 
          CloseNetworkConnection(connection_id) 
          Break 
        Else 
          Delay(Sleep) 
        EndIf 
      EndIf 
    ForEver 
  EndIf
EndProcedure

#server_protocol = "HTTP/1.1" 

#server = "purebasic.mybb.ru"
#page = "index.php"

#port = 80 

#buffer_size = 4096 
#timeout = 20000 
#sleep = 25 

Debug GetHTTP(#server, #page, #port, #server_protocol, #buffer_size, #sleep, #timeout)

0


Вы здесь » PureBasic - форум » PureBasic для Windows » Запрос к серверу