C Socket sendto Неверный аргумент - PullRequest
0 голосов
/ 01 мая 2018

Мой файл router.c создает 2 сокета во-первых, привязать порт и ответить клиентам второе - подключиться к уже связанному порту (с помощью файла server.c). и отправлять сообщения. по какой-то причине строка sendto возвращает ошибку Invalid argument. пожалуйста, помогите.

#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;
}

1 Ответ

0 голосов
/ 01 мая 2018

Вы никогда не заполните client_C_addr. Вы должны указать sendto, куда отправлять данные, например:

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");
...