Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

server-client aplikacja problem synchornizacji

Ostatnio zmodyfikowano 2017-12-04 12:04
Autor Wiadomość
aaadam
Temat założony przez niniejszego użytkownika
server-client aplikacja problem synchornizacji
» 2017-12-01 11:58:32
hej :)
piszę program na 2 boardy używam beagle bone, na jednym boardzie jest server na drugim klient.
Pierwszy board wysyła z czujników tempreature ale czas pomiaru jest długi około 2 sekund i gdy mam dużo żądań to nie zawsze dochodzi pakiet, natomiast jeżeli żądania są rzadko np co 3 seknudy to działa za każdym razem. używam tansmisji po nrf24l01.
Przerobiłem aplikacje pongtest i pingtest. proszę o pomoc a poniżej kody 2 aplikacji. żadanie wysyłam poprzez przeglądarkę np:
http://192.168.7.3:5001/
pingtest.cpp
C/C++
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include "RF24.h"
#define BUFOR_SIZE 32

char bufor[ BUFOR_SIZE ];
void doprocessing( int sock );
int readRequset( int sock );
RF24 radio( 115, 117 );
const int role_pin = 7;
const uint64_t pipes[ 2 ] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
typedef enum { role_ping_out = 1, role_pong_back } role_e;
const char * role_friendly_name[] = { "invalid", "Ping out", "Pong back" };
role_e role;

void setupRadio( void ) {
    role = role_ping_out;
    printf( "\n\rRF24/examples/pingpair/\n\r" );
    printf( "ROLE: %s\n\r", role_friendly_name[ role ] );
    radio.begin();
    radio.setRetries( 15, 15 );
    radio.setChannel( 0x4c );
    radio.setPALevel( RF24_PA_MAX );
    radio.openWritingPipe( pipes[ 0 ] );
    radio.openReadingPipe( 1, pipes[ 1 ] );
    radio.printDetails();
}

void getRadioData( void ) {
    unsigned long time = __millis();
    printf( "Now sending %lu...", time );
    bool ok = radio.write( & time, sizeof( unsigned long ) );
    memset( bufor, 0, BUFOR_SIZE );
   
    if( ok )
         printf( "ok..." );
    else {
        printf( "failed.\n\r" );
        sprintf( bufor, "error" );
        return;
    }
    radio.startListening();
    unsigned long started_waiting_at = __millis();
    bool timeout = false;
    while( !radio.available() && !timeout ) {
        __msleep( 5 );
        if( __millis() - started_waiting_at > 20000 )
             timeout = true;
       
    }
    if( timeout ) {
        printf( "Failed, response timed out.\n\r" );
    }
    else {
        unsigned long got_time;
        radio.read( & bufor, BUFOR_SIZE );
        printf( "Got response %s \n\r", bufor );
    }
    radio.stopListening();
}

int main( int argc, char ** argv ) {
    setupRadio();
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    char buffer[ 256 ];
    struct sockaddr_in serv_addr, cli_addr;
    int n, pid;
    sockfd = socket( AF_INET, SOCK_STREAM, 0 );
    if( sockfd < 0 ) {
        perror( "ERROR opening socket" );
        exit( 1 );
    }
   
    bzero(( char * ) & serv_addr, sizeof( serv_addr ) );
    portno = 5001;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons( portno );
    if( bind( sockfd,( struct sockaddr * ) & serv_addr, sizeof( serv_addr ) ) < 0 ) {
        perror( "ERROR on binding" );
        exit( 1 );
    }
   
    listen( sockfd, 5 );
    clilen = sizeof( cli_addr );
    while( 1 ) {
        newsockfd = accept( sockfd,( struct sockaddr * ) & cli_addr, & clilen );
        if( newsockfd < 0 ) {
            perror( "ERROR on accept" );
            exit( 1 );
        }
       
        pid = fork();
        if( pid < 0 ) {
            perror( "ERROR on fork" );
            exit( 1 );
        }
       
        if( pid == 0 ) {
            printf( "\n\n" );
           
            if( readRequset( newsockfd ) == 1 ) { //http request
                //printf("entering loop\n");
                getRadioData();
                doprocessing( newsockfd );
            }
            //else
            //printf("mot entering loop\n");
           
            close( sockfd );
            close( newsockfd );
            exit( 0 );
        }
        else {
            close( newsockfd );
        }
    }
    return 0;
}

int sendMessage( int socket, char * data ) {
    return write( socket, data, strlen( data ) );
}

int readRequset( int sock ) {
    int n;
    char buffer[ 256 ];
    bzero( buffer, 256 );
    n = read( sock, buffer, 255 );
   
    if( n < 0 ) {
        perror( "ERROR reading from socket" );
        exit( 1 );
    }
    if( buffer[ 5 ] != ' ' )
         return - 1;
   
    char buf[ 1024 ];
    int r = recv( sock, buf, 1024, 0 );
    fflush( stdout );
    return 1;
}

void doprocessing( int sock ) {
    sendMessage( sock, "HTTP/1.0 200 OK\r\n" );
    sendMessage( sock, "Content-Length: 32\r\n" );
    sendMessage( sock, "Content-Type: text/html\r\n" );
    sendMessage( sock, "Connection: Closed\r\n\r\n" );
    write( sock, bufor, BUFOR_SIZE );
}

pongtest.cpp
C/C++
#include <ctime>
#include <time.h>
#include <cstdlib>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include "RF24.h"
#define BUFOR_SIZE 32
static unsigned long ActualTemp;
static char bufor[ BUFOR_SIZE ];
RF24 radio( 115, 117 );
const int role_pin = 7;
const uint64_t pipes[ 2 ] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
typedef enum { role_ping_out = 1, role_pong_back } role_e;
const char * role_friendly_name[] = { "invalid", "Ping out", "Pong back" };
role_e role;

void GetTemp() {
    //      printf("gettemp\n");
    memset( bufor, 0, BUFOR_SIZE );
   
    DIR * d;
    struct dirent * dir;
    d = opendir( "/sys/devices/w1_bus_master1/" );
    if( d ) {
        int i = 0;
        while(( dir = readdir( d ) ) != NULL ) {
            if( dir->d_name[ 0 ] == '2' && dir->d_name[ 1 ] == '8' ) {
                char currentDir[ 100 ] = "/sys/devices/w1_bus_master1/";
                strcat( currentDir, dir->d_name );
                strcat( currentDir, "/w1_slave" );
                FILE * plik = 0;
                char f_bufor[ 256 ];
                plik = fopen( currentDir, "r" );
                if( !plik ) {
                    printf( "error file\n" );
                    exit( - 1 );
                }
                while( fgets( f_bufor, 256, plik ) ) { }
                int c = 0;
                char sub[ 6 ];
                short position = 30;
                short shift = 1;
                while( c < 7 ) {
                    if( c == 2 )
                    {
                        sub[ c ] = '.';
                        shift++;
                    }
                    else {
                        sub[ c ] = f_bufor[ position + c - shift ];
                    }
                    c++;;
                }
                sub[ 6 ] = '\0';
                char increment[ 1 ];
                sprintf( increment, "%ld", i );
                sscanf( sub, "%d", & ActualTemp );
                strcat( bufor, "t" );
                strcat( bufor, increment );
                strcat( bufor, " " );
                strcat( bufor, sub );
                strcat( bufor, " " );
                fclose( plik );
                i++;
            }
        }
        closedir( d );
    }
    //         printf("buffer temp |%s|\n",bufor);
}

void setupRadio( void ) {
    role = role_pong_back;
    printf( "\n\rRF24/examples/pingpair/\n\r" );
    printf( "ROLE: %s\n\r", role_friendly_name[ role ] );
    radio.begin();
    radio.setRetries( 15, 15 );
    radio.setChannel( 0x4c );
    radio.setPALevel( RF24_PA_HIGH );
   
    if( role == role_ping_out )
    {
        radio.openWritingPipe( pipes[ 0 ] );
        radio.openReadingPipe( 1, pipes[ 1 ] );
    }
    else
    {
        radio.openWritingPipe( pipes[ 1 ] );
        radio.openReadingPipe( 1, pipes[ 0 ] );
    }
   
    radio.startListening();
    radio.printDetails();
}
void loop( void ) {
    if( radio.available() ) {
        //GetTemp();
        unsigned long got_time;
        bool done = false;
        while( !done ) {
            done = radio.read( & got_time, sizeof( unsigned long ) );
            printf( "Got payload %lu...", got_time );
            delay( 20 );
            //                      GetTemp();
        }
        radio.stopListening();
        //tGetTemp();
        printf( "Sent response. %s \n\r", bufor );
        radio.write( & bufor, sizeof( char ) * BUFOR_SIZE );
        GetTemp();
        radio.startListening();
    }
}
int main( int argc, char ** argv ) {
    setupRadio();
    GetTemp();
    int z = 0;
    clock_t start = clock();
   
    while( 1 )
    {
        //GetTemp();
        //              if(start + 3 * CLOCKS_PER_SEC /* czas + 3s */ <= clock()){
        //              GetTemp();
        //               start = clock();
        //printf("tmp %s \n",buffor);
       
        //              }
        loop();
    }
    return 0;
}
P-167431
darko202
» 2017-12-01 14:42:10
nie programowałem na beagle bone, dlatego są to tylko dywagacje ale

1.
na
http://tmrh20.github.io/RF24​/classRF24.html#af2e409e62d49a23e372a70b904ae30e1
pisze, że

C/C++
// void RF24::startListening  ( void   ) 

// Start listening on the pipes opened for reading.
// 1.Be sure to call openReadingPipe() first.
// 2.Do not call write() while in this mode, without first calling stopListening().
// 3.Call available() to check for incoming traffic, and read() to get it.

//Open reading pipe 1 using address CCCECCCECC
byte address[] = { 0xCC, 0xCE, 0xCC, 0xCE, 0xCC };
radio.openReadingPipe( 1, address );
radio.startListening();


// void RF24::stopListening  ( void   ) 
// Stop listening for incoming messages, and switch to transmit mode.
// Do this before calling write().

radio.stopListening();
radio.write( & data, sizeof( data ) );

Ty otwierasz kanały komunikacyjne w identyczny sposób w metodzie setupRadio
jest startListening, a nie ma stopListening(); dla pisania

2.
 podobnie widzę inne informacje np. w
 //bool RF24::write  ( const void *  buf, uint8_t  len   )
This blocks until the message is successfully acknowledged by the receiver or the timeout/retransmit maxima are reached.

Blokuje to do momentu potwierdzenia komunikatu przez odbiornik lub osiągnięcia maksymalnych limitów czasu / retransmisji.

+ inne które mówią o jakiś parametrach domyślnych które wpływają na czasy działania

ogólnie to potwierdzałoby to co opisujesz (działa po 3s)





P-167433
mateczek
» 2017-12-02 09:11:28
ja podobne rzeczy robię korzystając z wątków. Jeden wątek gada z urządzeniem i uaktualnia wartość pomiarową, np ze sterownika. A główny wątek odpowiada klientom.  Za wątkami przemawia fakt iż odczyt danych z urządzenia, Wymiana danych (dogadanie się) np po RS232, może trochę czasu zająć (często urządzenia wymagają odczekania po wysłaniu komendy). Więc taką blokującą komunikację daje w wątku
P-167453
aaadam
Temat założony przez niniejszego użytkownika
» 2017-12-04 12:04:01
rozwąże ten problem za pomocą sekcji krytycznej, w danej chwili jeden wątek będzie mógł odczytywać temperaturę a reszta będzie dostawała temperaturę tymczasową.
P-167516
« 1 »
  Strona 1 z 1