I tried reworking the getaddrinfo() / getnameinfo() example from the man page, https://linux.die.net/man/3/getaddrinfo , which is built over datagram socket. My idea was to test these functions over stream socket, so I added listen() and accept() calls to establish the tcp. Client and server did talk to one another, but the getnameinfo() call failed to provide actual host/ service with error code :
-6 ( EAI_FAMILY The address family was not recognized, or the address length was invalid for the specified family. )
The sockets library is object oriented. However, it's written in C, so there's no compile-time enforcement of the interface. You have to do the right thing, and check return codes for errors. This is an example where C++ is faster because the checks can be done at compile time.
Think of sockaddr as a base class. sockaddr_in is a derived class for IPv4, sockaddr_in6 for IPv6 and so on. That's address type. All the calls specify sockaddr*, but it's really just an abstract base, that's why you have to cast your actual address type on use.
There's also protocol. In networking, we use datagrams, but we can use those to create streams. In IPv4, datagrams are available in protocol IPPROTO_UDP, you can send to and receive from anyone, the corresponding calls are sendto and recvfrom. The equivalent stream, IPPROTO_TCP, works on connected enpoints, so send and recv are sufficient, but you are required to connect or accept first. Any endpoint that's going to be connected to must first bind to known address, so it can be found.
BSD sockets also supports Novell's IPX/SPX, ... the system is open, you can plug in your own. It's pretty cool, once you get your head around it.
Some Winsock extension are not cool, like AcceptEx in the previous thread, the lovers of opaque abstractions getting it wrong again while trying to claw back performance from a clumsy design.
Wanna see how asio can be used with sockets? See BSD kqueue with asio on file descriptors. No crazy extensions to any of the subsystems.