套接字编程C - 绑定错误

时间:2018-02-05 13:30:02

标签: c sockets udp bind

我尝试创建一个函数来打开一个名为libf_build_udp_socket的套接字(我将来会有多个套接字)。但是当谈到绑定时我得到了错误cannot assign requested address,如果我绕过这个绑定,我发送一个cmd时出错了。 如果我不使用我的功能并直接集成我的主要代码,它就能很好地工作。

为了解释我在linux下有一台计算机必须发送cmd并从不同的设备接收日志,如信号接收器......

这是我的完整代码,所以也许你会更好地了解我的目标。

/* Standard Linux headers */
#include <stdio.h> //printf
#include <string.h> //memset
#include <stdlib.h> //exit(0);
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/times.h>
#include <unistd.h>
#include <errno.h>



/* DEFINE */
#define IP_RX "192.168.0.10" //notre IP=192.168.0.5
#define BUFFLEN 1024  //Max length of buffer
#define PORT_RX 3000   //The port on which to send data


unsigned short int libf_build_udp_socket(int * udp_socket, char * server_address, unsigned short int udp_port);

int main (void)
{

/*
   **  Definition of the local variables.
*/
  //SOCKET
  struct sockaddr_in addr_rx;
  int serv_len_rx=sizeof(addr_rx);
  int socket_fd_rx;
  unsigned short int socketStatus; /* Socket return status         */

  //FD
  fd_set readfds;


  //BUFFER & CMD
  char recepbuff[BUFFLEN];
  char cmd[BUFFLEN], cmd_final[BUFFLEN];

  //OTHER
  int i, recv;
  char choice;
  int loop=1;

  //TIMEOUT STRUCT
  struct timeval tv;
  tv.tv_sec=0; /*timeout de 0sec*/
  tv.tv_usec=1000; //NE MARCHE PAS SI =0

/*
    **  Initialisation of the local variables.
*/
memset(recepbuff, '0' ,sizeof(recepbuff)); /*pareil que bzero*/
i=0;



/*
   **  Creating the socket
   **  call socket (it creates an endpoint for communication and
   **                returns the socket descriptor.
   **                 To create an UDP socket here are the param
   **                 The protocol family should be AF_INET
   **                 The protocol type is SOCK_DGRAM
   **                 The protocol should beset to default ie
   **                 DEF_PROTOCOL wich is default so 0. );
*/


//OPENING AND SETTING SOCKET RX
socketStatus = libf_build_udp_socket(&socket_fd_rx, IP_RX, PORT_RX);
if (socketStatus>0)
{
  printf("Could not create the socket, code error %d\n", socketStatus);
  return 0;
}



/* Messaging*/
  while(1)
    {
      printf ("\n//Boucle %d\n", i);

      //clear the buffer by filling null, it might have previously received data
      memset(recepbuff, '\0' ,sizeof(recepbuff));
      loop=1;

      //preparing cmd
      printf("Enter command :");
      fgets(cmd, sizeof(cmd) , stdin);
      snprintf(cmd_final, sizeof (cmd_final), cmd, "\r\n"); /*adding 0d 0a to the cmd*/

      //send cmd
      if ( (sendto(socket_fd_rx , cmd_final, BUFFLEN , 0 , (struct sockaddr *)&addr_rx, serv_len_rx) ) < 0 )
        {
          perror("ERROR > send cmd failed to wass : ");
          return 0;
        }
        else
        {
            printf( "cmd send to %s:%d\n" ,inet_ntoa(addr_rx.sin_addr), ntohs(addr_rx.sin_port) );
        }

      //printf("\n... waiting answer from %s:%d ... \n" ,inet_ntoa(addr_rx.sin_addr), ntohs(addr_rx.sin_port) );
      //strcpy(recepbuff, "whileloop");


      //try to receive some data, this is a blocking call
        while(loop)
        {
            memset(recepbuff, '\0' ,sizeof(recepbuff)); //empty buffer

            FD_ZERO(&readfds);
            FD_SET(socket_fd_rx, &readfds); //set testing for rx

            select(socket_fd_rx+1, &readfds, NULL, NULL, &tv); //block until cmd becomes available
            if(FD_ISSET(socket_fd_rx, &readfds)) //input rx available
            {
                //printf("Data to be read \n");
                recvfrom( socket_fd_rx, recepbuff , BUFFLEN, 0, (struct sockaddr *)&addr_rx, &serv_len_rx); //recep
                printf("[=> Réponse : %s\n", recepbuff);
            }
            else
            {
                loop=0;
            }
        }

     printf(".... Réponse done from %s:%d .... \n",inet_ntoa(addr_rx.sin_addr),ntohs(addr_rx.sin_port) );
     i++;
    }

close(socket_fd_rx);
return 0;

}






//FONCTIONS

//OPENING 1 SETTING A SOCKET


/** libf_build_udp_socket
 *
 *  This function creates an UDP socket.
 *
 * \param udp_socket        socket identifier
 * \param server_address    IP destination address
 * \param udp_port      Destination UDP port
 * \param server_flag       TRUE to bind socket on UDP port
 *
 * \return 0 if successful; error code otherwise
 */
unsigned short int libf_build_udp_socket(int * udp_socket, char * server_address, unsigned short int udp_port)
{
  /*
   **  Defining of the local variables.
   */
  struct sockaddr_in serv_addr; /* Server Socket address structure*/
  short int status = 0; /* internal status return*/
  unsigned short int return_status = 0; /* the returnes status value */


  /*
   **  creating the socket ;
   **  call socket (it creates an endpoint for communication and
   **                returns the socket
   **                 descriptor. To create an UDP socket
   **                 the parameter family is set
   **                 to AF_INET, the type to SOCK_DGRAM, and
   **                 the protocol to
   **                 DEF_PROTOCOL. The socket is a global variable.);
   */
  *udp_socket = socket(AF_INET, SOCK_DGRAM, 0);

  if (*udp_socket < 0)
  {
    return_status = 1;
  }
  else
  {
    status = 1; //for future check

    if (status >= 0)
    {
      /*
       **  reset the serv_addr variable
       */
      bzero((char *) &serv_addr, sizeof(serv_addr));

      serv_addr.sin_family = AF_INET;

      /*
       **  set the sockname.sin_addr.s_addr to server address;
       **  sockname.sin_addr.s_addr = htonl(server address);
       **  set the sockname field sockname.sin_port to the used port number;
       **  sockname.sin_port = htons (udp port);
       */

      serv_addr.sin_addr.s_addr = inet_addr(server_address);
      serv_addr.sin_port = htons(udp_port);

       /*
         **  Bind this socket to a name;
         **  call bind (it assigns a name or address to an unnamed socket.
         **              When a socket is created with socket it exists in
         **              a name space (address family) but has no name assigned.
         **              The bind requests the name, be assigned to the socket);
         **  If  (return status signal an error)
         **  {
         **      set to return variable to error
         **  }
         */
      status = bind(*udp_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
      if (status < 0)
      {
        printf("bind failed with %s", strerror(errno));
        return_status = 2;
       }
    }
    else
    {
      return_status = 3;
    }
  }

  /*
   **  return status;
   */
  return return_status;
}

也许我缺少套接字编程中必不可少的东西,我做了很多研究并尝试了不同的东西,但它仍然不想工作!我将不胜感激!谢谢!

0 个答案:

没有答案