Reputation: 2259
Using a C89/C99 compiler, these two lines of code work
struct sockaddr_in server = { AF_INET, htons(27015), INADDR_ANY};
server.sin_addr.s_addr = inet_addr("127.0.0.1");
Is there a shorter version? For example, these do not work:
struct sockaddr_in server = { AF_INET, htons(27015), INADDR_ANY, inet_addr("127.0.0.1")};
struct sockaddr_in server = { AF_INET, htons(27015), INADDR_ANY, .sin_addr.s_addr = inet_addr("127.0.0.1") };
This unsightly long version works fine
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(27015);
server.sin_addr.s_addr = INADDR_ANY;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
The sockaddr_in has this format:
typedef struct sockaddr_in {
short sin_family;
USHORT sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;
Windows Client
https://godbolt.org/z/8q8GPxP54
Windows Server
https://godbolt.org/z/8j3ozKKxP
This suggested code does not connect
struct sockaddr_in server = { AF_INET, htons(27015), {inet_addr("127.0.0.1")}, {0} };
This code does connect
struct sockaddr_in serverX;
serverX.sin_family = AF_INET;
serverX.sin_addr.s_addr = INADDR_ANY;
serverX.sin_port = htons(27015);
serverX.sin_addr.s_addr = inet_addr("127.0.0.1");
Here's the difference between the versions. Notice, s_addr in server struct is 0x0000007f, whereas it's 0x0100007f in serverX:
Upvotes: 0
Views: 2068
Reputation: 223689
Two things: first, you've got the initalizer for sin_addr
in the wrong place. It's the third element in the struct, so the initializer should be third. Second, since sin_addr
is a struct type, you need to put its initializer in braces as well.
So what you want is:
struct sockaddr_in server={ AF_INET, htons(27015), {inet_addr("127.0.0.1")}, {0}};
As was mentioned in the comments however, condensing code onto one line usually isn't good practice because it can make code harder to read. Personally I'd prefer the long version as it makes it more clear to the reader which fields are being initialized with what.
Also note that this will only work on systems where the .s_addr
field is defined as a macro, as many systems do. For example, Windows (which you appear to be using) defines struct in_addr
as follows:
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
#define s_addr S_un.S_addr
/* can be used for most tcp & ip code */
#define s_host S_un.S_un_b.s_b2
/* host on imp */
#define s_net S_un.S_un_b.s_b1
/* network */
#define s_imp S_un.S_un_w.s_w2
/* imp */
#define s_impno S_un.S_un_b.s_b4
/* imp # */
#define s_lh S_un.S_un_b.s_b3
/* logical host */
};
As do many older UNIX distributions.
So to reiterate, use the code that's the most clear to the reader, not what fits on one line.
Upvotes: 1