Reputation: 101
I know the question has been asked already, but i seem to be some kind of "special" since my code doesn't work. Instruction is "bind with port 0 and use getsockname to get port". What am i doing wrong...
struct sockaddr_in sa;
sa.sin_port=htons(0);
sa.sin_addr.s_addr=htonl(INADDR_ANY);
sa.sin_family=AF_INET;
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr *serverptr = (struct sockaddr*)&sa;
bind(sock, serverptr,sizeof(sa));
socklen_t s=sizeof(sa);
int g=getsockname(sock,serverptr,&s);
g always prints as 0.
EDIT: it was so much simpler, just sa.sin_port Dumb question.
Upvotes: 0
Views: 1162
Reputation: 9827
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int
main (int argc, char** argv)
{
int sock;
struct sockaddr_in name;
char *addr;
if(argc<2) {
addr="0.0.0.0";
} else {
addr=argv[1];
}
/* Create the socket. */
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket");
exit (EXIT_FAILURE);
}
/* Give the socket a name. */
name.sin_family = AF_INET;
name.sin_port = htons (0);
name.sin_addr.s_addr = inet_addr(addr);
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
{
perror ("bind");
exit (EXIT_FAILURE);
}
int len = sizeof(name);
int sn = getsockname(sock, (struct sockaddr *)&name, &len);
printf("Port is %d\n",ntohs(name.sin_port));
return sock;
}
Compile: gcc getport.c -o getport
Usage: ./getport [address]
Ouput:
./getport
Port is 31725
./getport 127.0.0.1
Port is 32064
./getport 1.2.3.4
bind: Cannot assign requested address
Upvotes: 0
Reputation: 5369
Most of Berkley Socket API functions use very simple convention: result returned is the operation success indication. So, zero means OK, negative means error. To play safe, you have always to check it, and your code lacks this verification for the socket()
, bind()
, and getsockname()
calls:
...
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
// log the error, etc
return;
}
int res = bind(sock, serverptr, sizeof(sa));
if (res < 0) {
// log the error, etc
close(sock);
return;
}
socklen_t s = sizeof(sa);
res = getsockname(sock, serverptr, &s);
if (res < 0) {
// log the error, etc
close(sock);
return;
}
...
Upvotes: 1