2012-03-25 10 views
0

Ich habe ein Programm, das FEC-kodierende Daten ist und die Daten sendet; Empfangen der Daten an einem anderen Socket und Decodieren der Daten.'Sendto fehlgeschlagen'; Fehler bei der Verwendung von sendto-function unter Verwendung eines UDP-Sockets in C

Ich bekomme einen Fehler, wenn die sendto-Funktion in dem unten angehängten Code ausgeführt wird. Weitere Informationen zur sendto-Funktion finden Sie hier: Link Der Return-Code des Fehlers ist '-1'.

Was ist die Ursache für diesen Fehler und was muss ich im Code ändern, um es zu beheben?

Ausdrucke aus dem 'Empfänger':

*** Sender -- socket created 
***we have a client, and will sent message to server_addr ...server.. will receive messages.. sss 
*** Created server socket good. Server socket is 4 
***We have a server socket; and now we will try to bind it with the IP_ADDR-local host -- that we sent.. 
port nr 4783 & ip 127.0.0.1***Bind succeed.. 
Thread 1 

Einige Linien von eperftool.h

#define PORT_NUM 4783 // Arbitrary port number for the server 
    #define IP_ADDR  "127.0.0.1" // IP address of server1 (*** HARDWIRED ***) 
    #define SYMBOL_SIZE 1024 //todo..on a different position also 
    #define MAX_K  1000 
    #define MAX_N  1500 

Code of sender.c:

/* $Id: sender.c 3 2011-03-03 10:48:54Z detchart $ */ 
/* 
* OpenFEC.org AL-FEC Library. 
* (c) Copyright 2009-2011 INRIA - All rights reserved 
* Contact: [email protected] 
* 
* This software is governed by the CeCILL-C license under French law and 
* abiding by the rules of distribution of free software. You can use, 
* modify and/ or redistribute the software under the terms of the CeCILL-C 
* license as circulated by CEA, CNRS and INRIA at the following URL 
* "http://www.cecill.info". 
* 
* As a counterpart to the access to the source code and rights to copy, 
* modify and redistribute granted by the license, users are provided only 
* with a limited warranty and the software's author, the holder of the 
* economic rights, and the successive licensors have only limited 
* liability. 
* 
* In this respect, the user's attention is drawn to the risks associated 
* with loading, using, modifying and/or developing or reproducing the 
* software by the user in light of its specific status of free software, 
* that may mean that it is complicated to manipulate, and that also 
* therefore means that it is reserved for developers and experienced 
* professionals having in-depth computer knowledge. Users are therefore 
* encouraged to load and test the software's suitability as regards their 
* requirements in conditions enabling the security of their systems and/or 
* data to be ensured and, more generally, to use and operate it in the 
* same conditions as regards security. 
* 
* The fact that you are presently reading this means that you have had 
* knowledge of the CeCILL-C license and that you accept its terms. 
*/ 


/* AL-FEC extended performance evaluation tool */ 

#include "eperftool.h" 



/* 
* local variables 
*/ 
static void  **encoding_symbols_tab; /* temporary symbol array needed by the FEC encoder */ 

of_status_t 
init_sender (void) 
{ 
    of_session_t *ses;  /* pointer to a codec instance */ 
    block_cb_t *blk;  /* temporary pointer within the blk_cb_tab[] */ 
    UINT32  sbn;  /* block sequence number */ 
    UINT32  k;  /* k parameter for a given block. Warning, the last block might be shorter */ 
    UINT32  n;  /* n parameter for a given block. Warning, the last block might be shorter */ 
    UINT32  esi;  /* Encoding Symbol ID */ 
    UINT32  src_idx; /* index for a source symbol in the orig_symb[] table */ 
    UINT32  rep_idx; /* index for a repair symbol in the orig_symb[] table */ 
    symbol_cb_t *src_symb_cb; /* pointer to a source symbol in the orig_symb[] table */ 
    symbol_cb_t *rep_symb_cb; /* pointer to a repair symbol in the orig_symb[] table */ 
    UINT32  tmp_max_k; /* temporary value for max_k */ 
    UINT32  max_n_4_any_blk;/* maximum n value for any block */ 


#ifdef WIN32 
    QueryPerformanceCounter(&tv0); 
    OF_PRINT(("init_start=%lI64f\n", (double)tv0.QuadPart/(double)freq.QuadPart)) 
#else 
    gettimeofday(&tv0, NULL); 
    OF_PRINT(("init_start=%ld.%ld\n", tv0.tv_sec, tv0.tv_usec)) 
#endif 
    /* 
    * determine the blocking structure, which requires to create a temporary FEC session. 
    */ 
    if (of_create_codec_instance(&ses, codec_id, OF_ENCODER, of_verbosity) != OF_STATUS_OK) { 
     OF_PRINT_ERROR(("init_sender: ERROR: of_create_codec_instance() failed\n")) 
     goto error; 
    } 
    if (codec_id == OF_CODEC_REED_SOLOMON_GF_2_M_STABLE) { 
     if (of_set_control_parameter(ses, OF_RS_CTRL_SET_FIELD_SIZE, (void*)&rs_m_param, sizeof(rs_m_param)) != OF_STATUS_OK) { 
      OF_PRINT_ERROR(("init_sender: ERROR: of_set_control_parameter() failed\n")) 
      goto error; 
     } 
    } 
    if (of_get_control_parameter(ses, OF_CTRL_GET_MAX_K, (void*)&max_k, sizeof(max_k)) != OF_STATUS_OK) { 
     OF_PRINT_ERROR(("init_sender: ERROR: of_get_control_parameter() failed\n")) 
     goto error; 
    } 
    if (of_get_control_parameter(ses, OF_CTRL_GET_MAX_N, (void*)&max_n, sizeof(max_n)) != OF_STATUS_OK) { 
     OF_PRINT_ERROR(("init_sender: ERROR: of_get_control_parameter() failed\n")) 
     goto error; 
    } 
    if (of_release_codec_instance(ses) != OF_STATUS_OK) { 
     OF_PRINT_ERROR(("init_sender: ERROR: of_release_codec_instance() failed\n")) 
     goto error; 
    } 

    /* 
    * determine the practical maximum k and n parameters, taking into 
    * account the code/codec limitations and the desired code_rate. 
    * The idea is to have max_k maximum, given max_n and code_rate, for 
    * optimal erasure recovery performances. 
    */ 
    tmp_max_k = (UINT32)floor((double)max_n * code_rate); 
    max_k = min(tmp_max_k, max_k); 
    max_n = min((UINT32)((double)max_k/code_rate), max_n); 
    /* we can now compute the required blocking structure */ 
    of_compute_blocking_struct(max_k, object_size, symbol_size, &bs); 
    tot_nb_blocks = bs.nb_blocks; 
    /* 
    * adjust tot_nb_encoding_symbols and tot_nb_encoding_symbols variables, now we know 
    * the exact blocking structure. 
    */ 
    tot_nb_encoding_symbols = (bs.I * (int)floor((double)(bs.A_large)/code_rate)) + 
        ((bs.nb_blocks - bs.I) * (int)floor((double)(bs.A_small)/code_rate)); 

    ASSERT(tot_nb_encoding_symbols <= tot_nb_source_symbols + tot_nb_repair_symbols); 
    tot_nb_repair_symbols = tot_nb_encoding_symbols - tot_nb_source_symbols; 

    OF_PRINT_LVL(1, ("Blocking_struct:\n\ttot_nb_source_symbols=%d, tot_nb_repair_symbols=%d, tot_nb_encoding_symbols=%d, code_rate=%.3f\n\tI=%d, tot_nb_blocks=%d, A_large=%d, A_small=%d\n", 
     tot_nb_source_symbols, tot_nb_repair_symbols, tot_nb_encoding_symbols, code_rate, 
     bs.I, tot_nb_blocks, bs.A_large, bs.A_small)) 

    /* 
    * allocate and [email protected] the original source and repair symbol buffers. 
    */ 
    if ((orig_symb = (char**)calloc(tot_nb_encoding_symbols, sizeof(char*))) == NULL) { 
     OF_PRINT_ERROR(("init_sender: ERROR: out of memory\n")) 
     goto no_mem; 
    } 
    /* source symbol buffers first... */ 
    for (src_idx = 0; src_idx < tot_nb_source_symbols; src_idx++) { 
     char *symb; 
     UINT32 i; 
     /* 
     * buffer is 0'ed... Leave it like that, except for the first 
     * four bytes where we copy the pkt seq number. 
     */ 
     if ((symb = (char*)calloc(1, symbol_size)) == NULL) { 
      OF_PRINT_ERROR(("init_sender: ERROR: out of memory\n")) 
      goto no_mem; 
     } 
     orig_symb[src_idx] = symb; 
     /* fill each source symbol with some random content, except the first 
     * word which is equal to the symbol ID. This is useful to test the symbol 
     * integrity after decoding */ 
     for (i = 0; i < symbol_size; i++) { 
      symb[i] = (char)rand(); 

     } 
     *(UINT32 *)symb = (UINT32)src_idx; 
     //symb[src_idx%symbol_size]=1; 
     //of_print_composition(symb, symbol_size); 
    } 
    /* ... and then repair symbol buffers */ 
    for (rep_idx = tot_nb_source_symbols; rep_idx < tot_nb_encoding_symbols; rep_idx++) { 
      orig_symb[rep_idx] = (char*)calloc(1, symbol_size); 
     if (orig_symb[rep_idx] == NULL) { 
      OF_PRINT_ERROR(("init_sender: ERROR: out of memory\n")) 
      goto no_mem; 
     } 
     /* repair symbols will be initialized later... */ 
    } 
    /* 
    * now allocate the block and symbol control structures. 
    */ 
    if (!(blk_cb_tab = (block_cb_t*)calloc(tot_nb_blocks, sizeof(block_cb_t)))) { 
     OF_PRINT_ERROR(("init_sender: ERROR: out of memory\n")) 
     goto no_mem; 
    } 
    if (!(symb_cb_tab = (symbol_cb_t*)calloc(tot_nb_encoding_symbols, sizeof(symbol_cb_t)))) { 
     OF_PRINT_ERROR(("init_sender: ERROR: out of memory\n")) 
     goto no_mem; 
    } 
    /* ...and initialize the various block/symbol control structures */ 
    src_idx  = 0; 
    src_symb_cb = symb_cb_tab; 
    rep_idx  = tot_nb_source_symbols; 
    rep_symb_cb = &(symb_cb_tab[tot_nb_source_symbols]); 
    max_n_4_any_blk = 0; 
    for (sbn = 0, blk = blk_cb_tab; sbn < tot_nb_blocks; sbn++, blk++) { 
     if (sbn < (UINT32)bs.I) { 
      k = bs.A_large; 
     } else { 
      k = bs.A_small; 
     } 
     n = (UINT32)floor((double)k/code_rate); 
     max_n_4_any_blk = (n < max_n_4_any_blk) ? max_n_4_any_blk : n; 
     /* init block control block */ 
     blk->sbn   = sbn; 
     blk->k    = k; 
     blk->n    = n; 
     blk->first_src_symbol_idx = src_idx; 
     blk->first_repair_symbol_idx = rep_idx; 
     blk->is_decoded   = false; 
     blk->nb_symbols_received = 0; 
     OF_TRACE_LVL(1, ("init_sender: block: sbn=%d, k=%d, n=%d, first_src_symbol_idx=%d, 1st_rep_symbol_idx=%d\n", 
      sbn, blk->k, blk->n, 
      blk->first_src_symbol_idx, blk->first_repair_symbol_idx)) 
     /* init source symbols control block */ 
     for (esi = 0; esi < k; esi++, src_symb_cb++, src_idx++) { 
      src_symb_cb->esi = esi; 
      src_symb_cb->sbn = sbn; 
     } 
     /* and init repair symbols control block */ 
     for (esi = k; esi < n; esi++, rep_symb_cb++, rep_idx++) { 
      rep_symb_cb->esi = esi; 
      rep_symb_cb->sbn = sbn; 
     } 
    } 
    /* 
    * allocate the table containing the various symbols of a block. This table 
    * is allocated once and reused by all blocks of the object, with pointers to 
    * different symbols of course, for encoding purposes. 
    */ 
    if (!(encoding_symbols_tab = (void**)calloc(max_n_4_any_blk, sizeof(void*)))) { 
     OF_PRINT_ERROR(("init_sender: ERROR: out of memory\n")) 
     goto no_mem; 
    } 
#ifdef WIN32 
    QueryPerformanceCounter(&tv1); 
    OF_PRINT(("init_end=%I64f init_time=%I64f\n", 
     (double)tv1.QuadPart/(double)freq.QuadPart, 
     (double)(tv1.QuadPart-tv0.QuadPart)/(double)freq.QuadPart)) 
#else 
    gettimeofday(&tv1, NULL); 
    timersub(&tv1, &tv0, &tv_delta); 
    OF_PRINT(("init_end=%ld.%ld init_time=%ld.%06ld\n", 
     tv1.tv_sec, tv1.tv_usec, tv_delta.tv_sec, tv_delta.tv_usec)) 
#endif 

    //INIT SENDER SOCKET 
     // >>> Step #1 <<< 
     // Create a socket 
     // - AF_INET is Address Family Internet and SOCK_DGRAM is datagram 
     client_s = socket(AF_INET, SOCK_DGRAM, 0); 
     if (client_s < 0) 
     { 
     printf("*** ERROR - socket() failed \n"); 
     exit(-1); 
     } 
     printf("*** Sender -- socket created \n"); 
     // >>> Step #2 <<< 
     // Fill-in server1 socket's address information 
     server_addr.sin_family = AF_INET;     // Address family to use 
     server_addr.sin_port = htons(PORT_NUM);   // Port num to use 
     server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use 

       printf("***we have a client, and will sent message to server_addr ...server.. will receive messages.. sss\n"); 
    return OF_STATUS_OK; 
no_mem: 
error: 
    return OF_STATUS_ERROR; 
} 


of_status_t 
encode (void) 
{ 
    of_session_t *ses;  /* pointer to a codec instance */ 
    block_cb_t *blk;  /* temporary pointer within the blk_cb_tab[] */ 
    UINT32  sbn;  /* block sequence number */ 
    UINT32  k;  /* k parameter for a given block. Warning, the last block might be shorter */ 
    UINT32  n;  /* n parameter for a given block. Warning, the last block might be shorter */ 
    UINT32  esi;  /* Encoding Symbol ID */ 
    UINT32  i; 

    /* 
    * go through each block of the object, initialize all the structures 
    * and create repair symbols. 
    */ 
#ifdef WIN32 
    QueryPerformanceCounter(&tv0); 
    OF_PRINT(("encoding_start=%lI64f\n", (double)tv0.QuadPart/(double)freq.QuadPart)) 
#else 
    gettimeofday(&tv0, NULL); 
    OF_PRINT(("encoding_start=%ld.%ld\n", tv0.tv_sec, tv0.tv_usec)) 
#endif 
    for (sbn = 0, blk = blk_cb_tab; sbn < tot_nb_blocks; sbn++, blk++) { 
     k = blk->k; 
     n = blk->n; 
     /* don't forget to initialize the encoding symbol tab, used by the 
     * FEC codec during encoding, since we cannot use the orig_symb table 
     * where the source/repair symbols of a block are not sequential :-(*/ 
     for (esi = 0; esi < k; esi++) { 
      encoding_symbols_tab[esi] = (void*)(orig_symb[blk->first_src_symbol_idx + esi]); 
     } 
     for (; esi < n; esi++) { 
      encoding_symbols_tab[esi] = (void*)(orig_symb[blk->first_repair_symbol_idx + (esi - k)]); 
     } 
     /* 
     * create the codec instance and initialize it accordingly. 
     * The case of a parity check matrix given in a file is handled 
     * differently... 
     */ 
#ifdef OF_USE_LDPC_FROM_FILE_CODEC 
     if (codec_id == OF_CODEC_LDPC_FROM_FILE_ADVANCED) 
     { 
      if (of_create_codec_instance(&ses, codec_id, OF_ENCODER, of_verbosity) != OF_STATUS_OK) { 
       OF_PRINT_ERROR(("ERROR: of_create_codec_instance() failed for codec_id %d\n", codec_id)) 
       goto error; 
      } 
      of_ldpc_ff_parameters_t  params; 
      params.encoding_symbol_length = symbol_size; 
      params.pchk_file  = ldpc_matrix_file_name; 
      if (of_set_fec_parameters(ses, (of_parameters_t*)&params) != OF_STATUS_OK) { 
       OF_PRINT_ERROR(("ERROR: of_set_fec_parameters() failed for codec_id %d\n", codec_id)) 
       goto error; 
      } 
      k = params.nb_source_symbols; 
      n = params.nb_source_symbols + params.nb_repair_symbols; 
     } else 
#endif 
     { 
      ses = create_and_init_codec_instance(codec_id, OF_ENCODER, k, n, blk); 
      if (ses == NULL) { 
       OF_PRINT_ERROR(("ERROR: create_and_init_codec_instance() failed for codec_id %d/OF_ENCODER\n", codec_id)) 
       goto error; 
      } 
     } 
     /* 
     * perform encoding and finally release the FEC codec instance. 
     */ 
     for (esi = k; esi < n; esi++) { 
      if (of_build_repair_symbol(ses, encoding_symbols_tab, esi) != OF_STATUS_OK) { 
       OF_PRINT_ERROR(("ERROR: of_build_repair_symbol() failed\n")) 
       goto error; 
      } 
     } 

//SEND THE PACKETS TO THE RECEIVE!!! 
#ifdef WIN 
    WORD wVersionRequested = MAKEWORD(1,1);  // Stuff for WSA functions 
    WSADATA wsaData;        // Stuff for WSA functions 
#endif 
    int     server_s;  // Server socket descriptor 
    struct sockaddr_in server_addr;  // Server Internet address 
    struct sockaddr_in client_addr;  // Client Internet address..i.e //receiver 
    struct in_addr  client_ip_addr; // Client IP address 
    int     addr_len;  // Internet address length 
    char     out_buf[symbol_size]; // Output buffer for data 
    char     in_buf[symbol_size]; // Input buffer for data 
    int     retcode;   // Return code 

#ifdef WIN 
    // This stuff initializes winsock 
    WSAStartup(wVersionRequested, &wsaData); 
#endif 


    // >>> Step #3 <<< 
    // Now send the message to server. The "+ 1" is for the end-of-string 
    // delimiter 

      printf("*** Start sending messages.. \n"); 

    //n is number of symbols to sent -- repair + original.. 
int j= 0; 
    for (j=0; j < n ; j++) 
     { 
    //fprintf ("sending test..first char is %c and %c",(char*) ///encoding_symbols_tab[j]); 
     retcode = sendto(client_s, (const void*) encoding_symbols_tab[j], symbol_size, 0, 
     (struct sockaddr *)&server_addr, sizeof(server_addr)); 

     if (retcode < 0) 
     { 
     printf("*** ERROR - sendto() failed.. retcode is %d \n", retcode); 
     exit(-1); 
     } 
     else 
     printf("*** ERROR - sendto() successs \n"); 

     } 

einige Code der Empfänger:

// >>> Step #1 <<< 
    // Create a socket 
    // - AF_INET is Address Family Internet and SOCK_DGRAM is datagram 
    server_s = socket(AF_INET, SOCK_DGRAM, 0); 
    if (server_s < 0) 
    { 
    printf("*** ERROR - socket() failed \n"); 
    exit(-1); 
    } 
    else 
    printf("*** Created server socket good. Server socket is %d \n", server_s); 


    // >>> Step #2 <<< 
    // Fill-in my socket's address information 
    server_addr.sin_family = AF_INET;     // Address family to use 
    server_addr.sin_port = htons(PORT_NUM);   // Port number to use 
    server_addr.sin_addr.s_addr = htonl(IP_ADDR); // Listen on any IP address 
    printf("***We have a server socket; and now we will try to bind it with the IP_ADDR-local host -- that we sent.. \n port nr %d & ip %s", PORT_NUM, IP_ADDR); 

    retcode = bind(server_s, (struct sockaddr *)&server_addr, 
    sizeof(server_addr)); 

    if (retcode < 0) 
    { 
    printf("*** ERROR - bind() failed \n"); 
    exit(-1); 
    } 
else 
    printf("***Bind succeed.. \n"); 


//Storing all messages in in_buf -- here we will receive one; rest in code in decode-function. 

// >>> Step #3 <<< 
    // Wait to receive a message from client 
pthread_t thread1; 
int iret1; 
char *message1 = "Thread 1"; 

iret1 = pthread_create(&thread1, NULL,  waitToReceiveMessageFromClient, (void*) message1); 
+0

wenn retcode == -1: überprüfen errno. – wildplasser

+0

Danke! Ich fand diesen Vorschlag auch anderswo nach dem Posten. Jetzt bekomme ich 'errno ist Adresse Familie nicht vom Protokoll unterstützt'; und wird Google diesen Fehler. Es sollte ziemlich einfach zu lösen sein. –

+0

Mit errno habe ich gefunden "Adresse Familie nicht von Protokoll unterstützt" . Der Code in der Spitze von sender.c im Zusammenhang mit server_addr wurde nicht verwendet-es war nur lokal '. Die Variable server_addr wurde fälschlicherweise erneut initialisiert ohne Einstellung ‚sin_family‘ usw. => Fehler ich den folgenden Code in der Datei verschoben und jetzt funktioniert es: \t // Adresse server1 Buchse des-in geben Sie bitte Informationen \t server_addr.sin_family = AF_INET; // Zu verwendende Adressfamilie \t server_addr.sin_port = htons (PORT_NUM); // Zu verwendende Portnummer \t server_addr.sin_addr.s_addr = inet_addr (IP_ADDR); // IP-Adresse zu verwenden –

Antwort

1
#include <stdlib.h> 
#include <errno.h> 
#include <strings.h> 

... 

retcode = some_system_call(...); 
if (retcode == -1) 
    { 
    int err = errno; 
    fprintf(stderr, "*** ERROR - bind() failed:%d(%s)\n" 
     , err, strerror(err) 
    ); 
    exit(EXIT_FAILURE); 
    } 

BTW: Es gibt auch perror ist()

+0

Danke! Wie ich in meiner Antwort auf den obigen Kommentar gesehen habe, habe ich das kürzlich getan und bekam "Adressfamilie nicht vom Protokoll unterstützt". Nachdem ich diese Diagnose erhalten hatte, löste ich das Problem leicht. –

+1

Ein paar Kommentare 1) werfen Sie nicht den Rückgabewert von malloc() et.al. 2) Verwenden Sie nicht Exit (-1) 3) Druck Diagnoseausgang zu stderr, nicht stdout. 4) Wenn du stdint.h hast: benutze es. Wenn nicht: Die UINT32 wird vorerst gut funktionieren. – wildplasser

Verwandte Themen