Adresy IP w tablicy, socket w pętli, xml, mysql

0

Witam,

Muszę napisać program, który w pętli będzie łączył się po UDP z 100 adresów IP (od 10.0.7.1 do 10.0.7.100), pobierał z każdego XML i wpisywał go do bazy MySQL.

Na razie zawiesiłem się na pętli, która powinna co kilka sekund łączyć się po kolei z każdym adresem, nie mam problemów, gdy jest jedno IP, ale nie wiem już jak określić 100 takich adresów (bez 100 zmiennych ;))

Kod wygląda tak:

 #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

int main()
{
int sock, i, j=1, buffsize = 1024;
struct sockaddr_in server_addr;
struct hostent *host;
char send_data[1], *recv_data = malloc(buffsize);

if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket");
exit(1);
}

server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(6666);

sprintf(send_data, "\0");

   while (1)
   {

    host = (struct hostent *) gethostbyname((char *) "127.0.0.1");
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    bzero(&(server_addr.sin_zero),8);

    sendto(sock, send_data, strlen(send_data), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
    if (recv(sock, recv_data, buffsize, 0) == -1)
      perror("recvfrom()");
    
    printf("Received data: %s\n\n", recv_data);

    sleep(2);
 
   }

}

Mógłby mi ktoś podpowiedzieć jak zapisać te 100 adresów i po nich iterować? W sumie to zapisać głównie, dalej powinienem sobie poradzić. Program musi działać w nieskończoność, dlatego nie ma return itp. ;)

1
char* ipPattern = "10.0.7.%d";
int first = 1;
int last = 100;

char* ip = (char*)malloc((strlen(ipPattern) + 2) * sizeof(char));
for(int i = first; i < last + 1; i++)
{
	sprintf(ip, ipPattern, i);
	//...
}
free(ip);
0

Jeśli zdefiniuję

char *ipPattern = "10.0.7.%d";

to się kompiluje, ale przy próbie uruchomienia mam "naruszenie ochrony pamięci" :/
Kompiluję pod gcc na debianie.

1

Hmm. Być może przeoczyłem coś głupiego, ale...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
	char* ipPattern = "10.0.7.%d";
	int first = 1;
	int last = 100;
	int i = first;
	
	char* ip = (char*)malloc((strlen(ipPattern) + 2) * sizeof(char));
	for(; i < last + 1; i++)
	{
		sprintf(ip, ipPattern, i);
		
		printf("%d: %s\n", i, ip);
	}
	free(ip);
}
revik:/home/rev# gcc ip.c -o ip && ./ip
1: 10.0.7.1
2: 10.0.7.2
...
98: 10.0.7.98
99: 10.0.7.99
100: 10.0.7.100
revik:/home/rev#
0

Ok, już działa, nie wiem gdzie był błąd w sumie...

teraz mam cały kod tak:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

int main()
  {
    int sock, buffsize = 1024, first = 1, last = 100, i = first;
    struct sockaddr_in server_addr;
    struct hostent *host;
    char send_data[1], *recv_data = malloc(buffsize);
    char* ipPattern = "127.0.0.%d";

    if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
      {
        perror("socket");
        exit(1);
      }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(6666);

    sprintf(send_data, "\0");
    
    while(1)
      {
        for(; i < last + 1; i++)
          {
            char* ip = (char*)malloc((strlen(ipPattern) + 2) * sizeof(char));

            sprintf(ip, ipPattern, i);

            printf("curr: %s\n", ip);

            host = (struct hostent *) gethostbyname(ip);
            server_addr.sin_addr = *((struct in_addr *) host->h_addr);
            bzero(&(server_addr.sin_zero),8);

            sendto(sock, send_data, strlen(send_data), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
            if(recv(sock, recv_data, buffsize, 0) == -1)
              {
                perror("recvfrom()");
              }

            printf("Received data: %s\n\n", recv_data);

            free(ip);
            sleep(1);
          }
        i = first;
      }
  }

Wielkie dzięki!

Mam jeszcze jedno pytanie.
Dane, które odbieram i są w zmiennej recv_data, to xml, z którego muszę odczytać 3 liczby, a potem zapisać je w bazie MySQL, w PHP nie miałbym z tym żadnego problemu, ale w C nigdy czegoś takiego nie robiłem :< Mógłbyś podpowiedzieć jak to będzie mniej więcej wyglądać?
Wystarczą nazwy funkcji jakich powinienem użyć, bo zanim znajdę coś odpowiedniego na google minie kilka h, a nie mogę stracić tyle czasu...
Czy może lepiej i łatwiej będzie to inaczej odczytać? Jakieś wyrażenie regularne?

0

Możesz użyć libxml albo posixowych regexpów.

0

Próbowałem użyć http://xmlsoft.org/xmlreader.html ale przy próbie kompilacji dostaję:
error: libxml/xmlreader.h: Nie ma takiego pliku ani katalogu

0

To może zainstaluj najpierw ;)? apt-get install libxml-devel albo coś w tym stylu; poszukaj na stronie.

0

Program działa już w 95%, więc wrzucam, może komuś się przyda ;)

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <my_global.h>
#include <mysql.h>

static void saveMySQL(char *node_name)
  {
    MYSQL *conn;
    
    conn = mysql_init(NULL);
    if(conn == NULL)
      {
        printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
      }

    if(mysql_real_connect(conn, "localhost", "amokuser", "amok", "amok", 3306, NULL, 0) == NULL)
      {
        printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
      }

    char* stmt_pattern = "INSERT INTO cpu_temp VALUES('111', '%s', '10.0')";
    char* stmt = (char *)malloc((strlen(stmt_pattern) + strlen(node_name)) * sizeof(char));
    sprintf(stmt, stmt_pattern, node_name);
    printf("stmt: %s\n", stmt);
    mysql_real_query(conn, stmt, strlen(stmt));

    free(stmt);
    mysql_close(conn);
  }

static void get_element_names(xmlNode * a_node)
  {
    xmlNode *cur_node = NULL;
    char cpu_temp[5], node_name[9];

   for(cur_node = a_node; cur_node; cur_node = cur_node->next)
      {
        if(cur_node->type == XML_ELEMENT_NODE && xmlStrcmp(cur_node->name, (const xmlChar *)"NAME") == 0)
          {
            char* nodeName = (char*)malloc((strlen(xmlNodeGetContent(cur_node))) * sizeof(char));
            sprintf(nodeName, (char *)xmlNodeGetContent(cur_node));
            printf("zapisane: %s\n", nodeName);
            saveMySQL(nodeName);
            free(nodeName);
          }
          
        //saveMySQL(nodeName);

        //free(nodeName);
         
        get_element_names(cur_node->children);
      }
  }

static void AMOK_xml_parse(char *content, int length) {
    xmlDocPtr doc; /* the resulting document tree */
    xmlNode *root_element = NULL;

    /*
     * The document being in memory, it have no base per RFC 2396,
     * and the "noname.xml" argument will serve as its base.
     */

    doc = xmlReadMemory(content, length, "noname.xml", NULL, 0);
    if(doc == NULL)
      {
        fprintf(stderr, "Failed to parse document\n");
	return;
      }
    else
      {
        root_element = xmlDocGetRootElement(doc);
        get_element_names(root_element);
      }
    xmlFreeDoc(doc);
}

int main()
  {
    int sock, buffsize = 1024, first = 1, last = 100, i = first;
    struct sockaddr_in server_addr;
    struct hostent *host;
    char send_data[1], *recv_data = malloc(buffsize);
    char* ipPattern = "127.0.0.%d";

    LIBXML_TEST_VERSION

    if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
      {
        perror("socket");
        exit(1);
      }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(6666);

    sprintf(send_data, "\0");
    
    while(1)
      {
        for(; i < last + 1; i++)
          {
            char* ip = (char*)malloc((strlen(ipPattern) + 2) * sizeof(char));

            sprintf(ip, ipPattern, i);

            printf("curr: %s\n", ip);

            host = (struct hostent *) gethostbyname(ip);
            server_addr.sin_addr = *((struct in_addr *) host->h_addr);
            bzero(&(server_addr.sin_zero),8);

            sendto(sock, send_data, strlen(send_data), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
            if(recv(sock, recv_data, buffsize, 0) == -1)
              {
                perror("recvfrom()");
              }

            printf("Received data: %s\n\n", recv_data);

            AMOK_xml_parse(recv_data, strlen(recv_data));

            free(ip);
            sleep(1);
          }
        i = first;
      }
  }

Jakbyś ktoś zauważył jakieś błędy to jestem otwarty na propozycje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1