foxy_86
foxy_86

Reputation: 21

C Socket sendto Invalid argument error

My router.c file creates 2 sockets the first is to bind to a port and answer clients the second is to connect to an already bound port (by the server.c file) and send messages to. for some reason the sendto line return an Invalid argument error. please help.

#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>


    /* The Rounter represents through the server file(recv_udp.c).It transmitting  from/to  A(client) and C(another client)
    by specific criteria (given in the assignment). */


int main(int argc, char *argv[])
{
  /* Adding values that`ll be used for Q5*/
  char serMsg [] = "Nice to hear from you,I am the server\n";
  // char serMsg [] = "Good morning sun shine\n";
  int serMsgLeng = strlen(serMsg)+1;
  int error = -1;
  char buff_A[200] =  {'\0'};
  char buff_C[200] =  {'\0'};
  // A value we get from the command prompt
  float x;

  float random, rand_num;

  struct timeval tv;
  tv.tv_sec = 3;  /* 3 Seconds Time-out */
  tv.tv_usec = 0;

  /* Values that`ll receive for the  socket I`ll open (as socket descriptor(an int) etc.) */  
  int socket_fd1,socket_fd2, cc, addrLenA, s_in2Size;

  /* Randome number Raffled  between the range of[0,1]    */
  double randNum;

  /* Defining Structures for decleration of the server s_in= as serverAddr(local ip,and local port),
    from_A = the address that the datagram was received from client A,
    from_C-the address that the datagram was received from client C . */  
  struct sockaddr_in s_in1, s_in2;

  // Defining Structures for handling the clients address(client A and client C)
  // Client A address structure 
  struct sockaddr_in client_A_addr;

  //Client C address structure 
  struct sockaddr_in client_C_addr;

  x = atof(argv[1]);

  // Creating UDPsocket-(it`s a system call)-the socket()function opens a local socket and saves it`s number in socket_fd value. */
  socket_fd1 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  socket_fd2 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  /*set the socket options*/
  setsockopt(socket_fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
  setsockopt(socket_fd2, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));

  // Binary cleaning /
  bzero((char *) &s_in1, sizeof(s_in1));  /* They say you must do this    */
  bzero((char *) &s_in2, sizeof(s_in2));

  /*  Configure settings in address struct
"s_in.sin_family"-set the address family to be "AF_INET
"s_in.sin_addr.s_addr"- the htonl function converts host's to network's long
"s_in.sin_port" -the htons function converts regular form port to binary form.*/


  s_in1.sin_family = (short)AF_INET;//host byte order
  s_in1.sin_addr.s_addr = htonl(INADDR_ANY);    // WILDCARD //
  s_in1.sin_port = htons(1337);
  s_in2.sin_family = (short)AF_INET;//host byte order
  s_in2.sin_addr.s_addr = inet_addr("172.17.0.15");    // WILDCARD //
  s_in2.sin_port = htons(1338);

  //  printsin( &s_in, "RECV_UDP", "Local socket is:"); 
  fflush(stdout);

  /*  The bind function assigns a local protocol address to a socket(and another system call).
  The purpose of sin here is to tell bind which local address to assign.
  bind method input:the sock_fd and the stuctur that handels the address and it`s length*/
  bind(socket_fd1, (struct sockaddr *)&s_in1, sizeof(s_in1));
  printf("After binding,waiting to hear from clients!\n");

  addrLenA = sizeof(client_A_addr);

  s_in2Size = sizeof(s_in2);
  connect(socket_fd2, (struct sockaddr *) &s_in2, s_in2Size);
  printf("After connect to server!\n");

    // Keep listenning 
  for(;;) {

    // Check from who we recive the message - if from cilent A 

    // Check for errors 
    //recfrom() returns the length of the message that it receives,so if the client message length that the method returns is 
    //equal to the message length of client A - we raffel a number between[0,1].
    if( (cc = recvfrom(socket_fd1,&buff_A,sizeof(buff_A),0,(struct sockaddr*)&client_A_addr,&addrLenA))== error){
        printf("No message for now, waiting...\n");
    }
    // For self-check ,no error occured
    if (strlen(buff_A) > 0) {
      printf("Client A says: %s\n", buff_A);

      // Than raffel a randNum and decide what to do with it(send or delete it)
      srand(time(NULL));
      random = rand();
      rand_num = random / RAND_MAX;
      printf("rand_num: %f\n", rand_num);
      printf("x: %f\n", x);

      // Greater than X send it
      if(rand_num > x) {
        printf("Sending message From A to C\n");
        // Pass the message to C
        if(sendto(socket_fd2, &buff_A, sizeof(buff_A),0,(struct sockaddr*)&client_C_addr,sizeof(client_C_addr))== error){
          printf("sendto()- Client C failes to send message\n"); 
          printf("%s\n", strerror(errno));
          exit(1);
        }
      } else {
        // Drop the message
      }

      // Clearing the message buffer
      memset(buff_A, '\0', sizeof buff_A);
    } 
  } //end for
  return 0;
}

Upvotes: 2

Views: 1200

Answers (1)

mnistic
mnistic

Reputation: 11020

You never fill in client_C_addr. You must tell sendto where to send the data, like:

client_C_addr.sin_family = AF_INET;
client_C_addr.sin_port = htons(port);
client_C_addr.sin_addr.s_addr = inet_addr("192.168.1.1");

Upvotes: 2

Related Questions