Search code examples
csocketsudpbuffersendto

Sending a single unsigned char through a socket using UDP in C


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



}

Solution

  • 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.