0

The title says it all, it might be a simple thing but I'm pretty much new at programming hence the stupid question..

I have:

printf("sourcemsg: %s", inet_ntoa(sourceMsgs[j].sin_addr));

to see if the ip address that is saved in sourceMsgs[j] is the correct one and it was so I'm assuming the problem is at:

nbytes = sendto(s, response , reslen, 0 , (struct sockaddr *)&sourceMsgs[i],sizeof(sourceMsgs));
            //    (uk: save the coordinates/address of the source of the received message
            //    in table sourceMsgs at index nReceivedMessages).

            //I'm pretty sure what I did here is wrong

            int j = nReceivedMessages;
            sourceMsgs[j].sin_addr = cli_addr.sin_addr;
            printf("sourcemsg: %s", inet_ntoa(sourceMsgs[j].sin_addr));
            nReceivedMessages++;
            total += receivedValue;

            printf("<Servidor> Valor recebido: %f\n", receivedValue);
            //(uk: <Server> Received value)

            if(nReceivedMessages == 1){


                timeout = 1;
                setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(DWORD));

            }

        }

    }

    sprintf(response,  "Received Messages: %f Total: %f", nReceivedMessages, total);

    int reslen = sizeof(response);

    for(i=0; i<nReceivedMessages; i++){

        //    (uk: transmit the content of variable response, the previously defined string, to
        //    all the destinations in table sourceMsgs).

        nbytes = sendto(s, response , reslen, 0 , (struct sockaddr *)&sourceMsgs[i],sizeof(sourceMsgs));

I apologise if the post is extremely incomplete but it is my first one. Thank you for the help in advance

Edit:

It seems the problem is indeed with passing the length of the structure (WSAError 10014). The code is like this now:

nbytes = sendto(s, response , strlen(response), 0 , (struct sockaddr *)&sourceMsgs[i].sin_addr, sizeof(sourceMsgs[i].sin_addr));

I'm not really sure what to do, but there probably is a different way to do:

               sourceMsgs[j].sin_addr = cli_addr.sin_addr;
               printf("sourcemsg: %s", inet_ntoa(sourceMsgs[j].sin_addr));
               nReceivedMessages++;
               total += receivedValue;

since I think the way I did it is a but screwed up.

Jan Frank
  • 3
  • 2

2 Answers2

0

The argument to sendto should be a pointer to the sockaddr structure, not the structure that contains it.

nbytes = sendto(s, response , reslen, 0 , (struct sockaddr *)&sourceMsgs[i].sin_addr,sizeof(sourceMsgs[i].sin_addr));

Barmar
  • 741,623
  • 53
  • 500
  • 612
0

There might be a problem with passing the length of the structure.

nbytes = sendto(s, response, reslen, 0, (struct sockaddr *)&sourceMsgs[i], sizeof(sourceMsgs[i]));

// sizeof(sourceMsgs) gives - ( sizeof(sourceMsgs[1] or struct sockaddr_in) * (No. of messages in array) ).

Also, I noticed a problem setting recv timeout using setsockopt. See SO_RCVTIMEO for explanation.

  • If there is still a problem, kindly tell me where the problem occurred. – Karthik Chennupati Oct 31 '19 at 04:20
  • About the timeout setting I'm aware there's a problem, but I'll fix that after. And you're right about the passing of the length of the structure, it was pointed out as WSAerror 10014, but I don't know how to pass it correctly... – Jan Frank Nov 01 '19 at 14:30
  • just pass it as I have posted or you can even say `sizeof(struct sockaddr_in)`. – Karthik Chennupati Nov 01 '19 at 17:44
  • if I pass it like you said, I get error 10047 (Address family not supported by protocol family), if I do `(struct sockaddr *)&sourceMsgs[i].sin_addr, sizeof(sourceMsgs[i].sin_addr)` I get error 10014 (Bad address) – Jan Frank Nov 01 '19 at 18:31
  • The sendto() function takes the message to be sent, it's length, the socket from which we want that message to be sent, the destination socket's details as a structure and the length of that structure, if that makes any sense. In your code, you passed socket, message, message length correctly. But, you are sending destination system's sin_addr only. You need to send the entire structure and the length of that structure. – Karthik Chennupati Nov 02 '19 at 02:52
  • i.e., `sendto(s, response, reslen, 0, (struct sockaddr *)&sourceMsgs[i], sizeof(sourceMsgs[i]));`. Observe how I passed the destination socket details. The destination socket details are stored in a structure of type `sockaddr_in`, and you have an array of such structures. So, we need to pass the address of that structure casted to type `struct sockaddr *`, since it is what sendto() is expecting. If you're using UNIX based computer, consider typing `man sendto` in your terminal and read about that function. You'll understand it better. – Karthik Chennupati Nov 02 '19 at 02:59
  • First time, you passed the structure correctly and size of the structure incorrectly. Second time, you passed structure incorrectly and size of structure correctly. You might have followed Barmar's code below. – Karthik Chennupati Nov 02 '19 at 03:03
  • About the error 10047, see if the socket you're sending data from is binded with sockaddr_in structure and the members of both source and destination socket's sockaddr_in are initialised correctly. See https://www.binarytides.com/programming-udp-sockets-c-linux/ for a brief tutorial. – Karthik Chennupati Nov 02 '19 at 03:10
  • well it's working now, it ended up being the part where I assign cli_addr to sourceMsgs[j], I had tried that before but for some reason it hadn't worked but it's running as expected now. Thanks for your help! – Jan Frank Nov 04 '19 at 13:55