[FUG-BR] Fwd: "Clonar" conexão
Otacílio
otacilio.neto em bsd.com.br
Seg Jun 19 15:23:09 BRT 2017
Em 19/06/2017 09:59, Renato Frederick escreveu:
> Em 19 de junho de 2017 09:27, Otacílio <otacilio.neto em bsd.com.br
> <mailto:otacilio.neto em 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;
}
Mais detalhes sobre a lista de discussão freebsd