⟩ What is Socket Addressing?
A Socket Address is a host.port pair (communication is between host.port pairs -- one on the server, the other on the client). We know how to determine host numbers and service numbers so we're well on our way to filling out a structure were we specify those numbers. The structure is sockaddr_in, which has the address family is AF_INET as in this fragment:
int tcpopen(host,service)
char *service, *host;
{ int unit;
struct sockaddr_in sin;
struct servent *sp;
struct hostent *hp;
etc...
if ((sp=getservbyname(service,"tcp"))
== NULL) then error...
if ((hp=gethostbyname(host)) == NULL)
then error...
bzero((char *)&sin, sizeof(sin));
sin.sin_family=AF_INET;
bcopy(hp->h_addr,(char *)&sin.sin_addr,
hp->h_length);
sin.sin_port=sp->s_port;
etc...
The code fragment is filling in the IP address type AF_INET, port number and IP address in the Socket Address structure -- the address of the remote host.port where we want to connect to find a service.
There's a generic Socket Address structure, a sockaddr, used for communication in arbitrary domains. It has an address family field and an address (or data) field:
/* from: /usr/include/sys/socket.h */
struct sockaddr {
u_short sa_family; /*address family */
char sa_data[14];/*max 14 byte addr*/
};
The sockaddr_in structure is for
Internet Socket Addresses
address family AF_INET). An instance
of the generic socket address.
/* from: /usr/include/netinet/in.h */
struct sockaddr_in {
short sin_family; /* AF_INET */
u_short sin_port; /* service port */
struct in_addr sin_addr; /*host number */
char sin_zero[8]; /* not used */
};
The family defines the interpretation of the data. In other domains addressing will be different -- services in the UNIX domain are names (eg. /dev/printer). In the sockaddr_in structure we've got fields to specify a port and a host IP number (and 8 octets that aren't used at all!). That structure specifies one end of an IPC connection. Creating that structure and filling in the right numbers has been pretty easy so far.