最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Missing parameter in sockaddr_in initialization - Stack Overflow

programmeradmin2浏览0评论

I'm following an online tutorial for a [very] simple web server. It works, but the initialization of sockaddr_in() is missing a parameter. So I'm not sure why it does work and not sure what I should use for the missing parameter to make my IDE parser happy.

The program:

#include <sys/socket.h>
#include <string.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <unistd.h>
#include <netinet/in.h>

int main(void) {
    int s = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr = {
        AF_INET,
        0x901f, // the hex code for 8080 (little endian)
        0
    };

    bind(s, &addr, sizeof(addr));
    listen(s, 10);

    int client_fd = accept(s, 0, 0);

    char buffer[256] = {0};
    recv(client_fd, buffer, 256, 0);

    char* f = buffer + 5;
    *strchr(f, ' ') = 0;
    int opened_fd = open(f, O_RDONLY);
    sendfile(client_fd, opened_fd, 0, 256);
    close(opened_fd);
    close(client_fd);
    close(s);
    return 0;
}

The library definition:

/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;         /* Port number.  */
    struct in_addr sin_addr;        /* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr)
               - __SOCKADDR_COMMON_SIZE
               - sizeof (in_port_t)
               - sizeof (struct in_addr)];
  };

Compile errors:

$ gcc -o server server.c
server.c: In function ‘main’:
server.c:16:13: warning: passing argument 2 of ‘bind’ from incompatible pointer type [-Wincompatible-pointer-types]
   16 |     bind(s, &addr, sizeof(addr));
      |             ^~~~~
      |             |
      |             struct sockaddr_in *
In file included from server.c:1:
/usr/include/x86_64-linux-gnu/sys/socket.h:112:49: note: expected ‘const struct sockaddr *’ but argument is of type ‘struct sockaddr_in *’
  112 | extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
      |                                                 ^

EDIT: Added compile errors and fixed semantics.

I'm following an online tutorial for a [very] simple web server. It works, but the initialization of sockaddr_in() is missing a parameter. So I'm not sure why it does work and not sure what I should use for the missing parameter to make my IDE parser happy.

The program:

#include <sys/socket.h>
#include <string.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <unistd.h>
#include <netinet/in.h>

int main(void) {
    int s = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr = {
        AF_INET,
        0x901f, // the hex code for 8080 (little endian)
        0
    };

    bind(s, &addr, sizeof(addr));
    listen(s, 10);

    int client_fd = accept(s, 0, 0);

    char buffer[256] = {0};
    recv(client_fd, buffer, 256, 0);

    char* f = buffer + 5;
    *strchr(f, ' ') = 0;
    int opened_fd = open(f, O_RDONLY);
    sendfile(client_fd, opened_fd, 0, 256);
    close(opened_fd);
    close(client_fd);
    close(s);
    return 0;
}

The library definition:

/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;         /* Port number.  */
    struct in_addr sin_addr;        /* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr)
               - __SOCKADDR_COMMON_SIZE
               - sizeof (in_port_t)
               - sizeof (struct in_addr)];
  };

Compile errors:

$ gcc -o server server.c
server.c: In function ‘main’:
server.c:16:13: warning: passing argument 2 of ‘bind’ from incompatible pointer type [-Wincompatible-pointer-types]
   16 |     bind(s, &addr, sizeof(addr));
      |             ^~~~~
      |             |
      |             struct sockaddr_in *
In file included from server.c:1:
/usr/include/x86_64-linux-gnu/sys/socket.h:112:49: note: expected ‘const struct sockaddr *’ but argument is of type ‘struct sockaddr_in *’
  112 | extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
      |                                                 ^

EDIT: Added compile errors and fixed semantics.

Share Improve this question edited Feb 16 at 19:10 Mike asked Feb 16 at 18:45 MikeMike 8142 gold badges8 silver badges17 bronze badges 13
  • sockaddr_in is a structure, not a function. You don't call it... – Shawn Commented Feb 16 at 18:57
  • 1 If this tutorial you found has things like void main() and no error checking like your code is showing, I'd drop it like a hot potato in favor of something better. – Shawn Commented Feb 16 at 19:01
  • 1 And are you asking about the warning message you get (not an error)? Have you tried to actually read it? It is quite clear, and how to use the bind function should be well-documented in any decent book or tutorial. And the way to solve it should be known to anyone that has passed the beginners stage of learning C. – Some programmer dude Commented Feb 16 at 19:08
  • 3 struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(8080) }; and maybe something like this afterwards inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr) – Memos Electron Commented Feb 16 at 19:20
  • 1 You have to cast the address of your structure like (const struct sockaddr *)&addr in the call to bind(). This is normal - bind() can accept many types of address. – pmacfarlane Commented Feb 16 at 20:45
 |  Show 8 more comments

1 Answer 1

Reset to default 1

You wrote:

        AF_INET,
        0x901f, // the hex code for 8080 (little endian)
        0

It's better to use:

        .sin_family = AF_INET,
        .sin_port = htonh(8080), // in decimal :)
        .sin_addr = { .s_addr = INADDR_ANY },  // (a wildcard)

You don't need to change INADDR_ANY to network byte order as it is already in that format.

Also, the second parameter of bind(2) is required to be a struct sockaddr * so better if you cast your data, as in:

    int res = bind(s, (const struct sockaddr *)&addr, (socklen_t)sizeof(addr));

and, of course, check the returned value of bind() for errors.

发布评论

评论列表(0)

  1. 暂无评论