为何accept()、recv()函数中地址长度参数为指针而非socklen_t类型?
addrlen is a pointer in accept() and similar functions like recvfrom()? Great question—this is one of those Unix network API design choices that trips up a lot of developers at first, but once you unpack the reasoning, it clicks immediately. Let’s break this down clearly:
For accept()
When you call accept(), you’re asking the kernel to pull a pending connection from the listen socket’s queue and share details about the remote peer. Here’s why addrlen needs to be a pointer:
- It’s an input first: You set the
socklen_tvariable to the size of theaddrbuffer you’ve allocated (e.g.,sizeof(struct sockaddr_in)for IPv4,sizeof(struct sockaddr_in6)for IPv6). This tells the kernel, "This is how much space I have to store the remote address—don’t write beyond this." - It’s an output second: Once the kernel fills the
addrbuffer with the remote peer’s address, it needs to tell you the actual size of the address structure it wrote. Different address families (IPv4, IPv6, Unix domain sockets) have differently sizedsockaddrstructures. You need this real length to properly interpret the address later—for example, to cast a genericstruct sockaddrto the correct family-specific type.
If addrlen were a plain socklen_t instead of a pointer, the kernel could only read your input value—it couldn’t send the actual length back to your code. C uses pass-by-value for function arguments, so any changes to a non-pointer addrlen would only modify a local copy that gets discarded as soon as accept() returns.
For recvfrom() (the address-aware cousin of recv())
The logic here is nearly identical:
- Input: You pass the size of your
addrbuffer so the kernel knows not to overflow it when writing the sender’s address (critical for UDP sockets, where every packet comes from a potentially different source). - Output: The kernel tells you the actual size of the sender’s address structure. This lets you handle mixed address families (e.g., a socket that receives both IPv4 and IPv6 packets) by casting the generic
struct sockaddrto the right type based on the returned length.
The big picture
This is a classic Unix system API pattern: when a function needs to both take configuration from the caller and send additional information back, pointer parameters enable this two-way communication. You’ll see the same logic in functions like getaddrinfo() or readdir() too—it’s all about making the most of C’s pass-by-value semantics without sacrificing flexibility.
内容的提问来源于stack exchange,提问作者John_ABC

