开发者

C programming - Understanding bind()

I'm having trouble understanding the bind() function in regards to Unix Domain Sockets.

address.sun_family = AF_UNIX;
addrlen = sizeof(address.sun_family) + strlen(SOCK_PATH);
.
.
.
bind(socket_fd, (struct sockaddr *) &address, addrlen) != 0) 

As I understand currently, this takes the so开发者_如何学Gocket_fd (located in the processes namespace) that was created with socket(), and "applies" the address information contained in address to the socket. Essentially creating it so that other processes can use it.... I think that is correct.

What I don't understand is the need for the addrlen argument. This is the length of the address structure without leading/trailing null bytes. Correct? Is this argument necessary to tell bind() how many bytes to read out of address???

Thanks for your insight!


To put it simply, bind says to the system : okay, from now on, any packet with destination {address->sun_addr} should be forwarded to my socket_fd, so I can read them.

The addrlen argument specifies the size of the structure because different types of structure (of different sizes) can be passed. For example, struct sockaddr_un*, struct sockaddr_in*. A "common" structure is passed instead, struct sockaddr*, so bind does not know what is the real type of your structure. This is why you have to pass the length.

PS: I'm sure you meant process address space rather than process namespace.


Not sure why your addrlen is set like this, the correct/usual method is:

   memset(&addr, 0, sizeof(struct sockaddr_un));
                        /* Clear structure */
   addr.sun_family = AF_UNIX;
   strncpy(addr.sun_path, MY_SOCK_PATH,
            sizeof(addr.sun_path) - 1);

   if (bind(sfd, (struct sockaddr *) &addr,
            sizeof(struct sockaddr_un)) == -1) {
        perror("bind");
        exit(EXIT_FAILURE);
   }

note the use of sizeof(), no strlen/addrlen expected


I am also still learning, thats what brought me here, so maybe explaining my understanding will help me learn as well, so be weary, I may be very wrong, or I might be in the right direction...

You need it because IPv4 and IPv6 addresses are different lengths as are addresses of different protocols, I'd assume not all protocols such as Apple Talk or the Ham Radio protocols use addresses resembling IPv4 style addresses, which are a set of 4 bytes, octets I think they are called, separated by "."'s .

So when you call "sizeof(struct sockaddr_in)" You are passing in an "int" that is the number of bytes sockaddr_in consists of, which would be different from "sizeof(struct sockaddr_in6)" of sizeof(struct sockaddr_un). sockaddr_in is for inet or IPv4, *_in6 is for inet6 or IPv6, and *_un is for Unix domain sockets. I believe Unix domain socket addresses are file paths that can only be used for local process communication. So for one, the function/method needs to know where the socket file is, such as /home/user/Pictures/socket so it can bind it to a local port, hence the strncopy and sun_path business. This may also apply to inet/6 sockets, winsocks maybe different. (Learning C/C++ on Windows was the closest to suicidal I have ever been).

The int that gets passed via "sizeof(struct sockaddr_un)" may be used to determine a mode of execution within the actual implementation code. if arg[2] = N do this;else if arg[2] = M do that???Maybe...

If you read the manual on sockets, you'll see that the example uses "sizeof()" and not addrlen.

Note: When attaining the size in bytes of your protocol's address structure, it doesn't matter if the struct your using actually contains useful data, you just need its size, this is why the struct is instantiated within the parameter, using "sizeof()" on the newly created struct returns the int that you need and that is what is used as the argument for the 3rd parameter.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜