1

I am trying to send a single unsigned char through a buffer. I am using a buffer of size 2

unsigned char temp_buf [2];
temp_buf [0]= (unsigned char) 0xff;
temp_buf [1]= NULL;

and my sendto functions looks like this:

if (sendto(fd, temp_buf, sizeof (temp_buf), 0, (struct sockaddr *)&remaddr, addrlen) < 0)
        perror("sendto");

It compiles with no issues, however at run time i get an error:

sendto: Invalid argument

Which means there is something wrong with the buffer im using. I suspected that the issue might be because im using siezeof so i changed it to strlen(temp_buf) but still no luck!

EDIT: I was trying to make the question simpler by not including the whole code but here it is, Sorry about that!

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "port.h"

#define BUFSIZE 2048

int
main(int argc, char **argv)
{
    struct sockaddr_in myaddr;  /* our address */
    struct sockaddr_in remaddr; /* remote address */
    socklen_t addrlen = sizeof(remaddr);        /* length of addresses */
    int recvlen;            /* # bytes received */
    int fd;             /* our socket */
    int msgcnt = 0;         /* count # of messages we received */
    unsigned char buf[BUFSIZE]; /* receive buffer */


    /* create a UDP socket */

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("cannot create socket\n");
        return 0;
    }

    /* bind the socket to any valid IP address and a specific port */

    memset((char *)&myaddr, 0, sizeof(myaddr));
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    myaddr.sin_port = htons(SERVICE_PORT);

    if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
        perror("bind failed");
        return 0;
    }

    /* now loop, receiving data and printing what we received */



        printf("waiting on port %d\n", SERVICE_PORT);

        //recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);

        //buf [0] = 0xff;
        unsigned char temp_buf [2];
        temp_buf [0]= (unsigned char) 0xff;
        temp_buf [1]= '\0';

        if (sendto(fd, temp_buf, sizeof (temp_buf), 0, (struct sockaddr *)&remaddr, addrlen) < 0)
            perror("sendto");
        else
            printf("%s \n", "Communication established");



}
az_1993
  • 27
  • 8
  • `temp_buf [1]= NULL;` --> `temp_buf [1]= '\0';` – David Ranieri Aug 08 '16 at 17:16
  • @AlterMann I already tried that but it didnt work – az_1993 Aug 08 '16 at 17:18
  • 1
    How do you populate `remaddr` and `addrlen`? – dbush Aug 08 '16 at 17:23
  • Also, how do you create the socket? – dbush Aug 08 '16 at 17:35
  • @dbush I added the whole code. Thanks for helping out – az_1993 Aug 08 '16 at 17:39
  • the implicit conversion feature of the compiler is probably handling this for you. However, a `NULL` is the size of an address pointer (in a 32 bit system that is 4 bytes) but the posted code is trying to assign a single character with a 4 char value. Strongly suggest using: `'\0'` – user3629249 Aug 08 '16 at 23:08
  • the question has the statement: `#include "port.h"` but no contents for that file. – user3629249 Aug 08 '16 at 23:10
  • the posted code causes the compiler to raise several warning messages. Always fix warnings before trying to run. 1) unused variable: `buf[]`. 2) unused parameter: `argc` 3) unused parameter: `argv[]` 4) unused variable: `msgcmt`. 5) unused variable: `recvlen`. When compiling , always enable all the warnings, then fix those warnings. for the `main()` signature, strongly suggest: `int main( void )` – user3629249 Aug 08 '16 at 23:13

1 Answers1

1

The contents of remaddr are uninitialized. In other words, you're not telling sendto where to send the data.

You need to populate this struct with the IP and port you wish to send to.

If you uncomment the call to recvfrom and subsequently get a packet from some other service, remaddr gets populated with the IP/port that sent that packet, then you can use that to send a packet back. But without that, you need to fill in remaddr.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Thank you. I am fairly new to UDP socket programming. If my IP is 192.168.1.1 how can i initilize it? Also my port is 8899 which is in another header file called port.h. how can i assign these to remaddr? – az_1993 Aug 08 '16 at 17:46
  • 1
    @user3238603 For the IP you can do `remaddr.sin_addr.s_addr = inet_addr("192.168.1.1");` and `remaddr.sin_port = htons(8889);` for the port – dbush Aug 08 '16 at 17:49
  • it worked thanks so much! But one last thing, am i sending the unsigned chars correctly ? – az_1993 Aug 08 '16 at 17:54
  • @user3238603 What you're sending is fine. As long as the other end knows how to read it, there's no problem. – dbush Aug 08 '16 at 17:55
  • im getting >sendto: Adress family not supported by protocol would you happen to know why that might be happening – az_1993 Aug 08 '16 at 18:23
  • 2
    @user3238603 You also need to set `remaddr.sin_family = AF_INET`. – dbush Aug 08 '16 at 18:24