theeggman85
theeggman85

Reputation: 1825

UDP Socket in C - Setting it up wrong?

I'm working on a project that involves sending various requests to a server through UDP. However, I seem to be setting up the socket entirely wrong, as the server does not respond to any of my requests. We were provided with a server binary to test against, and the code below ellicits no response. Am I setting up the UDP socket correctly? If so, am I somehow using sendto wrong? I have confirmed that I am sending the correct number of bits.

The input for the program is: ./client [URL] [port] [username], and I always test with ./client localhost 8080 user. Here is the struct I am sending and the code.

struct request_login {
    int req_type; /* = REQ_LOGIN */
    char req_username[32];
} packed;

Code:

struct sockaddr_in sa;
int sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd == -1){
   printf("Could not create socket.");
   exit(EXIT_FAILURE);
}

// Prepare the socket address
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr(argv[1]);
// Convert to network order
sa.sin_port = htonl(atoi(argv[2]));

// Assemble and send login request
struct request_login * reqlogin = (struct request_login *) malloc(sizeof(struct request_login));
reqlogin->req_type = REQ_LOGIN;
strcpy(reqlogin->req_username, argv[3]);

int res = sendto(sockfd, reqlogin, sizeof (struct request_login), 0, (struct sockaddr*)&sa, sizeof sa);
free(reqlogin)

Upvotes: 1

Views: 276

Answers (3)

AndersK
AndersK

Reputation: 36082

try this instead:

struct addrinfo hint;
memset(&chk,0,sizeof(chk));
hint.ai_family = AF_INET;
hint.ai_socktype = SOCK_DGRAM;
hint.ai_protocol = IPPROTO_UDP;

struct addrinfo* servAddr = NULL;
int ret = getaddrinfo(argv[1],atoi(argv[2]),&hint,&servAddr);
if (-1 == ret)
{
  perror("getaddrinfo failed");
  exit(EXIT_FAILURE);
}

int sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd == -1){
   printf("Could not create socket.");
   exit(EXIT_FAILURE);
}

// Assemble and send login request
struct request_login reqlogin;
reqlogin.req_type = REQ_LOGIN;
strcpy(reqlogin.req_username, argv[3]);

int res = sendto(sockfd, &reqlogin, sizeof (struct request_login), 0, servAddr->ai_addr, servAddr->ai_addrlen);

Upvotes: 1

unwind
unwind

Reputation: 399703

Huh?

This:

sa.sin_addr.s_addr = inet_addr(argv[1]);

certainly won't do the right thing if, as you say, argv[1] is typically "localhost". You need to look up the host name, so that you get an IP address. You can only use inet_addr() if the input is a dotted IP address, not a host name.

Look at getaddrinfo().

Upvotes: 3

Some programmer dude
Some programmer dude

Reputation: 409136

After re-reading your code a couple of times, I think I know what one cause of the error may be:

sa.sin_port = htonl(atoi(argv[2]));

The port number is a short so you should use htons instead. It's very small and easy to miss.

Upvotes: 2

Related Questions