Em 19/06/2017 09:59, Renato Frederick escreveu:
Em 19 de junho de 2017 09:27, Otacílio <otacilio.n...@bsd.com.br <mailto:otacilio.n...@bsd.com.br>> escreveu:


    Em 19/06/2017 07:45, Renato Frederick escreveu:



    A comunicação é feita por TCP ou UDP?

    []'s

    -Otacílio


Olá Otacílio! É TCP.

Explicando melhor: O que acontece é que eu tenho um GPS na moto e ele envia atualização para um servidor web que montei(ao invés de usar estes da china que não tem muito recurso, ou pagar 20 a 30 reais nos brasileiros). Lá mostra meu histórico, define cercas(entrou ou saiu do espaço definido manda SMS/email), etc.

Porém no GPS eu envio um comando indicando IP e porta do servidor que ele vai usar. não posso usar DNS porque a maioria das telemetria não manda DNS direito ou o meu GPS não entende.

E eu sempre estou desenvolvendo e melhorando o software, fazendo isto na máquina de casa, que tem IP ADSL dinâmico.

Não quero tirar o GPS de usar o IP de producao e colocar em testes, pois às vezes o gps fica meio doido, tem que dar reset, quero mexer nele menos possível, até porque quanto menos eu mexer melhor, pois em uma emergência eu preciso ter na hora a localização, depois que eu bloquear a moto, já que muitos meliantes são tão tranquilos que mesmo bloqueado abrem o banco e começam a procurar, então tempo é importante.

Então eu queria colocar no GPS o IP fixo que já tenho a produção, porém em outra porta(1234) e daí nesta porta usar o NETCAT que vai jogar a string(dados hexadecimais reportando longitude + hora/data) para a produção na porta certa(5023) e também lá em casa na mesma porta.

Assim, eu tenho garantia que tudo que ele registrar em um tem que aparecer no outro. Se não acontecer é que algo no programa está errado, pode ser algo que eu fiz.
Obrigado!


Escrevi este pequeno programa que quebra o seu galho.

Ele conecta no servidor de produção e espera a conexão do GPS e de um cliente espião. Tudo o que o GPS enviar ele vai enviar para o servidor de produção e para o cliente espião. Tudo o que o servidor ou o cliente enviar ele vai encaminhar para o GPS. É muito fácil de usar. Qualquer coisa entre em contato.

[]'s
-Otacílio

/**
 * Copyright(C) Otacílio de Araújo Ramos Neto
* Você pode fazer o que quiser com este software, exceto mudar esta licença e/ou dizer que foi você
 * quem escreveu.
 *
* Este software é distribuído acreditando-se que está correto e é totalmente funcional, mas sem * nenhuma garantia disso ou de que é adequado a um determinado fim. Use-o sob sua conta e risco.
 *
 * Para compilar use: cc -Wall -O2 -pipe -o gpsc gpsc.c  -lpthread
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <getopt.h>             /* getopt_long() */

#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define BUFFER_SIZE 4*1024
#define BACKLOG 4

const char short_options[] = "s:p:l:c:";

const struct option
long_options[] = {
    { "server",  required_argument, NULL, 's' },
    { "port",    required_argument, NULL, 'p' },
    { "ouca",  required_argument, NULL,   'l' },
    { "client",  required_argument, NULL, 'c' },
    { 0,          0,                  0,       0  }
};

void help(char *nome);
int conectaServidorProducao(char *server, char *porta);
void *servidorProducao(void *p);
void *servidorCliente(void *p);
void *servidorGPS(void *p);
void sigpipe(int i);

char server[1024]="\0";
char porta[6]="\0";
char ouca[6]="\0";
char client[6]="\0";
int producaoSocket=-1;
int gpsSocket=-1;
int clienteSocket=-1;

int main(int argc, char **argv){
    pthread_t produServer, clienteServer, gpsServer;
    for (;;) {
        int idx;
        int c;

        c = getopt_long(argc, argv, short_options, long_options, &idx);

        if (-1 == c)
            break;

        switch (c) {
        case 0: // getopt_long() flag
            break;
        case 's':
            strncpy(server, optarg, sizeof(server));
            server[sizeof(server)-1] = '\0';
            break;
        case 'p':
            strncpy(porta, optarg, sizeof(porta));
            porta[sizeof(porta)-1] = '\0';
            break;
        case 'l':
            strncpy(ouca, optarg, sizeof(ouca));
            ouca[sizeof(ouca)-1] = '\0';
            break;
        case 'c':
            strncpy(client, optarg, sizeof(client));
            client[sizeof(client)-1] = '\0';
            break;
        default:
            help(argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    if(!strlen(server)){
fprintf(stderr, "Voce precisa informar o endereço do servidor de produção\n\n");
        help(argv[0]);
        exit(EXIT_FAILURE);
    }

    if(!strlen(porta)){
fprintf(stderr, "Voce precisa informar a porta do servidor de produção\n\n");
        help(argv[0]);
        exit(EXIT_FAILURE);
    }

    if(!strlen(ouca)){
fprintf(stderr, "Voce precisa informar a porta que deve ouvir o GPS\n\n");
        help(argv[0]);
        exit(EXIT_FAILURE);
    }

    if(!strlen(client)){
fprintf(stderr, "Voce precisa informar a porta que o cliente vai conectar\n\n");
        help(argv[0]);
        exit(EXIT_FAILURE);
    }

    signal(SIGPIPE, sigpipe);

    // Cria o thread responsável por conectar no servidor de produção
    if (pthread_create(&produServer, NULL, servidorProducao, NULL)) {
fprintf(stderr,"Erro ao criar o thread para comunicação com o servidorde produção.\n");
        exit(EXIT_FAILURE);
    }
    // Cria o thread responsável por ouvir o cliente
    if(pthread_create(&clienteServer, NULL, servidorCliente, NULL)){
fprintf(stderr, "Erro ao criar o thread para comunicação com o cliente espição.\n");
        exit(EXIT_FAILURE);
    }
    // Cria o thread responsável por ouvir o GPS
    if(pthread_create(&gpsServer, NULL, servidorGPS, NULL)){
fprintf(stderr, "Erro ao criar o thread para comunicação com o cliente GPS.\n");
        exit(EXIT_FAILURE);
    }

    pthread_join(produServer, NULL);
    pthread_join(clienteServer, NULL);
    pthread_join(gpsServer, NULL);

    printf("DEBUG\n");
    return 0;
}

void help(char *nome)
{
    fprintf(stderr,     "Voce deve usar: %s <options>\n"
"-s | --server nome de host Nome de host do servidor de produção\n"
    "-p | --port   porta no servidor    Porta do servidor de produção\n"
    "-l | --ouca   porta do GPS         Porta em que o GPS vai conectar\n"
"-c | --client porta do cliente Porta em que o cliente espião vai conectar\n", nome);
}

void sigpipe(int i)
{
    fprintf(stderr, "broken pipe\n");
}

int conectaServidorProducao(char *server, char *porta)
{
    struct addrinfo hints, *result = NULL, *ptr = NULL;
    int iResult;
    int producaoSocket=-1;

    bzero(&hints, sizeof(hints));

    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo(server, porta, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        exit(EXIT_FAILURE);
    }

    // Attempt to connect to an address until one succeeds
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        // Create a SOCKET for connecting to server
producaoSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (producaoSocket < 0){
            perror("socket");
            exit(EXIT_FAILURE);
        }

        // Connect to server.
iResult = connect( producaoSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == -1) {
            close(producaoSocket);
            producaoSocket = -1;
            continue;
        }

        break;
    }

    freeaddrinfo(result);

    if (producaoSocket == -1) {
           printf("Unable to connect to server %s:%s!\n", server, porta);
    }

    return producaoSocket;
}


int preparaConexao(uint16_t porta)
{
    int s;
    int optval;
    struct sockaddr_in sa;

    if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Nao foi possivel criar o socket servidor");
        exit(EXIT_FAILURE);
    }

    bzero(&sa, sizeof(sa));

    sa.sin_family = AF_INET;
    sa.sin_port   = htons(porta);

    if (INADDR_ANY)
        sa.sin_addr.s_addr = htonl(INADDR_ANY);

    // Configura o socket para reutilizar um endereço
    optval = 1;
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);

    if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        perror("Erro ao fazer o bind para o socket do cliente");
        exit(EXIT_FAILURE);
    }

    listen(s, BACKLOG);

    return s;
}

void *servidorCliente(void *p)
{
    int socket;
    socklen_t b;
    struct sockaddr_in sa;
    char buffer[BUFFER_SIZE];
    int lgpsSocket=-1;
    ssize_t nbytes;
    uint16_t porta = (int)strtol(client, (char **)NULL, 10);

    socket = preparaConexao(porta);

    b = sizeof(sa);

    for(;;){
if ((clienteSocket = accept(socket, (struct sockaddr *)&sa, &b)) < 0) {
            perror("(servidorClient) Erro na chamada accept");
            exit(EXIT_FAILURE);
        }

        printf("(servidorClient) cliente conectado\n");
        if(clienteSocket!=-1){
            do{
// Vamos esperar alguma coisa do servidor. Se chegar escreve no socket do GPS
                nbytes = read(clienteSocket, buffer, sizeof(buffer));

                if(lgpsSocket==-1 && gpsSocket!=-1)
                    if((lgpsSocket = dup(gpsSocket))==-1){
perror("(servidorCliente) Erro ao executar lgpsSocket = dup(gpsSocket)");
                    exit(EXIT_FAILURE);
                }

                if(nbytes>0){
                    if(lgpsSocket!=-1){
                        // Escreve a tralha do lado do GPS
                        if(write(lgpsSocket, buffer, nbytes) != nbytes){
fprintf(stderr, "(servidorClient) Pacote perdido, numero de bytes escritos no GPS diferente do lido do cliente\n");
                            lgpsSocket = -1;
                        }
                    }else if(lgpsSocket==-1){
fprintf(stderr, "(servidorClient) Pacote perdido, GPS socket fechado\n");
                    }else{
fprintf(stderr, "(servidorClient) Conexao fechada, nbytes = %zd\n", nbytes);
                    }
                }else if(nbytes==0){
                    fprintf(stderr, "(servidorClient) Socket fechado\n");
                }
            }while(nbytes>0);
            close(clienteSocket);
        }
        sleep(3);
    }

    return NULL;
}

void *servidorGPS(void *p)
{
    int socket;
    socklen_t b;
    struct sockaddr_in sa;
    char buffer[BUFFER_SIZE];
    int lproducaoSocket=-1;
    int lclienteSocket=-1;
    ssize_t nbytes;
    uint16_t porta = (int)strtol(ouca, (char **)NULL, 10);

    socket = preparaConexao(porta);

    b = sizeof(sa);

    for(;;){
        if ((gpsSocket = accept(socket, (struct sockaddr *)&sa, &b)) < 0) {
            perror("(servidorGPS) Erro na chamada accept");
            exit(EXIT_FAILURE);
        }
        printf("(servidorGPS) GPS conectado\n");
        if(gpsSocket!=-1){
            do{
// Vamos esperar alguma coisa do servidor. Se chegar escreve no socket do GPS
                nbytes = read(gpsSocket, buffer, sizeof(buffer));

                if(producaoSocket!=-1 && lproducaoSocket==-1){
                    if((lproducaoSocket=dup(producaoSocket))==-1){
perror("(servidorGPS) Erro ao executar lproducaoSocket=dup(producaoSocket)");
                        exit(EXIT_FAILURE);
                    }
                }
                if(clienteSocket!=-1 && lclienteSocket==-1){
                    if((lclienteSocket=dup(clienteSocket))==-1){
perror("(servidorGPS) Erro ao executar lclienteSocket=dup(clienteSocket)");
                        exit(EXIT_FAILURE);
                    }
                }

                if(nbytes>0){
                    if(lproducaoSocket!=-1){
                        // Escreve a tralha do lado do servidor
if(lproducaoSocket!=-1 && write(lproducaoSocket, buffer, nbytes) != nbytes){ fprintf(stderr, "(servidorGPS) Pacote perdido, numero de bytes escritos no servidor de producao diferente do lido do GPS\n");
                            lproducaoSocket = -1;
                        }
if(lclienteSocket!=-1 && write(lclienteSocket, buffer, nbytes) != nbytes){ fprintf(stderr, "(servidorGPS) Pacote perdido, numero de bytes escritos no cliente diferente do lido do GPS\n");
                            lclienteSocket = -1;
                        }
                    }else if(lproducaoSocket==-1){
fprintf(stderr, "(servidorGPS) Pacote perdido, producao socket fechado\n");
                    }else{
fprintf(stderr, "(servidorGPS) Conexao fechada, nbytes = %zd\n", nbytes);
                    }
                }else if(nbytes==0){
fprintf(stderr, "(servidorGPS) Socket do GPS fechado\n");
                }
            }while(nbytes>0);
            close(gpsSocket);
        }
        sleep(3);
    }

    return NULL;
}

void *servidorProducao(void *p)
{
    char buffer[BUFFER_SIZE];
    int lgpsSocket=-1;
    ssize_t nbytes;
    for(;;){
        producaoSocket=conectaServidorProducao(server, porta);
        if(producaoSocket!=-1){
printf("(servidorProducao) Conectado em %s:%s\n", server, porta);
            do{
// Vamos esperar alguma coisa do servidor. Se chegar escreve no socket do GPS
                nbytes = read(producaoSocket, buffer, sizeof(buffer));
                if(lgpsSocket==-1 && gpsSocket!=-1){
                    if((lgpsSocket=dup(gpsSocket))==-1){
perror("(servidorProducao) Erro ao executar lgpsSocket=dup(gpsSocket)");
                        exit(EXIT_FAILURE);
                    }
                }

                if(nbytes>0){
                    if(lgpsSocket != -1){
                        // Escreve a tralha do lado do GPS
                        if(write(lgpsSocket, buffer, nbytes) != nbytes){
fprintf(stderr, "(servidorProducao) Pacote perdido, numero de bytes escritos no GPS diferente do lido do servidor de producao\n");
                            lgpsSocket = -1;
                        }
                    }else if(lgpsSocket==-1){
fprintf(stderr, "(servidorProducao) Pacote perdido, GPS socket fechado\n");
                    }else{
fprintf(stderr, "(servidorProducao) Conexao fechada, nbytes = %zd\n", nbytes);
                    }
                }else if(nbytes==0){
                    fprintf(stderr, "(servidorProducao) Socket fechado\n");
                }
            }while(nbytes>0);
            close(producaoSocket);
        }
        sleep(3);
    }

    // Chega nunca aqui
    return NULL;
}

-------------------------
Histórico: http://www.fug.com.br/historico/html/freebsd/
Sair da lista: https://www.fug.com.br/mailman/listinfo/freebsd

Responder a