2012-03-25 26 views
0

我有一个程序,它是FEC编码数据,发送数据;在另一个套接字处接收数据,并对数据进行解码。'发送失败';使用Sendto函数时出错,使用C中的UDP套接字

当sendto函数在下面附加的代码中执行时出现错误。有关sendto函数的更多信息,请执行以下操作:Link 错误的返回码是'-1'。

这个错误的原因是什么?为了解决这个错误,我应该在代码中改变什么?

从 '接收器' 打印件:

*** 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 

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 

代码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"); 

     } 

的某些代码接收器:

// >>> 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

如果RETCODE == -1:检查errno。 – wildplasser 2012-03-25 15:20:59

+0

谢谢! 我也在发布后的其他地方发现了这个建议。 现在,我得到'errno是协议不支持的地址族';并将谷歌该错误。应该很容易解决。 – 2012-03-25 15:28:40

+0

使用errno我发现'不支持协议的地址族'' 。 与server_addr相关的sender.c顶部的代码未被使用 - 它只是本地的。变量SERVER_ADDR被误再次初始化没有设置“sin_family”等=>错误 我移动的文件在下面的代码,现在它正在努力: \t //填写-server1中套接字的地址信息 \t server_addr.sin_family = AF_INET; //地址族使用 \t server_addr.sin_port = htons(PORT_NUM); //要使用的端口号 \t server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP地址使用 – 2012-03-25 15:38:34

回答

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:还有PERROR()

+0

谢谢!正如我在回复上面的评论中看到的那样,我最近做了这件事,并得到了'不支持协议的地址族'。收到这个诊断后,我轻松解决了这个问题。 – 2012-03-25 15:40:27

+1

几点意见1)不要强制返回malloc()et.al. 2)不要使用exit(-1)3)将诊断输出打印到stderr,而不是标准输出。 4)如果你有stdint.h:使用它。当不是时:UINT32可能暂时会很好。 – wildplasser 2012-03-25 15:51:49

相关问题