UNP读书笔记--Chapter 3 Sockets Introduction

Socket Address Structure

Name of socket address structures begin with sockaddr_ and end with a unique suffix for each protocol suite.

IPv4 Socket Address Structure

IPv4 socket address structure is named sockaddr_in and is defined by including the<netinet/in.h> header.

IPv4 Socket Address Structure
struct in_addr {
    in_addr_t   s_addr;  /* 32*/
}

struct sockaddr_in {
    uint8_t      sin_len;
    sa_family_t  sin_family;
    in_port_t sin_port; 
    struct in_addr sin_addr;
    char sin_zero;
};

IPv6 Socket Address Structure


struct in6_addr {
    uint8_t		s6_addr[16];
};

struct sockaddr_in6 {
    uint8_t		sin6_len;
    sa_family_t	sin6_family;
    in_port_t	sin6_port;
    uint32_t	sin6_flowinfo;
    struct in6_addr	sin6_addr;
    uint32_t	sin6_scope_id;
};

The four socket functions that pass a socket address structure from the process to the kernel: bind, connect, sendto and sendmsg

The five socket functions that pass a socket address structure from the kernel to the process: accept, recvfrom, recvmsg, getpeername and getsockname.


Generic Socket Address

A problem arises in how to declare the type of pointer that is passed. With ANSI C, the solution is simple: void * is the generic pointer type. But, the socket functions 
predate ANSI C and the solution chosen in 1982 was to define a generic socket address structure in the <sys/socket.h> header,

struct sockaddr
{
    uint8_t sa_len;
    sa_family_t sa_family; /* address family: AF_xxx value */
    char sa_data[14];      /* protocol-specific address */
};

Byte Ordering Function

little-endian byte order: with the low-order byte at the starting address;

big-endian byte order: with the high-order byte at the starting address.

Unfortunately, there is no standard between these two byte orderings and we encounter systems that use both formats. We refer to the byte ordering used by a 
given system as the host byte order.

/* check os little-endian or big-endian byte order */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
	union
	{
		short s;
		char c[sizeof(short)];
	}un;

	un.s = 0x0102;
	if (sizeof(short) == 2)
	{
		if (un.c[0] == 1 && un.c[1] == 2)
			printf("big-endian\n");
		else if (un.c[0] == 2 && un.c[1] == 1)
			printf("little-endian\n");
		else
			printf("unknown\n");
	}
	else
		printf("sizeof(short) = %d\n", sizeof(short));

	exit(0);
}
We must deal with these byte ordering differences as network programmers because networking protocols must specify a network byte order.

The Internet protocols use big-endian byte ordering for these multibyte integers.

 We use the following four functions to convert between these two byte orders. 

#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue) ;
uint32_t htonl(uint32_t host32bitvalue) ;
                           Both return: value in network byte order
uint16_t ntohs(uint16_t net16bitvalue) ;
uint32_t ntohl(uint32_t net32bitvalue) ;
                           Both return: value in host byte order

Byte Manipulation Functions

There are two groups of functions that operate on multibyte fields,

The first group of functions, whose names begin with b (for byte), are from 4.2BSD and are still provided by almost any system that supports the socket functions.

#include <strings.h>
void bzero(void *dest, size_t nbytes);
void bcopy(const void *src, void *dest, size_t nbytes);
int bcmp(const void *ptr1, const void *ptr2, size_t nbytes);
                          Returns: 0 if equal, nonzero if unequal

The second group of functions, whose names begin with mem (for memory), are from the ANSI C standard and are provided with any system that supports an ANSI C library.

#include <string.h>
void *memset(void *dest, int c, size_t len);
void *memcpy(void *dest, const void *src, size_t nbytes);
int memcmp(const void *ptr1, const void *ptr2, size_t nbytes);
                        Returns: 0 if equal, <0 or >0 if unequal (see text)

memcpy  is similar to bcopy, but the order of the two pointer arguments is swapped. bcopy correctly handles overlapping fields, while the behavior of memcpy is undefined if the source and destination overlap. The ANSI C memmove  function must be used when the fields overlap.

 

Two groups of address conversion functions.

'inet_aton', 'inet_addr', and 'inet_ntoa' Functions

They convert Internet addresses between ASCII strings (what humans prefer to use) and network byte ordered binary values (values that are stored in socket address structures).

inet_aton, inet_ntoa, and inet_addr convert an IPv4 address from a dotted-decimal string (e.g., "206.168.112.96") to its 32-bit network byte ordered binary value.

#include <arpa/inet.h>
int inet_aton(const char *strptr, struct in_addr *addrptr);
                                    Returns: 1 if string was valid, 0 on error
in_addr_t inet_addr(const char *strptr);
                                    Returns: 32-bit binary network byte ordered IPv4 address; INADDR_NONE if error
char *inet_ntoa(struct in_addr inaddr);
                                    Returns: pointer to dotted-decimal string

'inet_pton' and 'inet_ntop' Functions

These two functions are new with IPv6 and work with both IPv4 and IPv6 addresses.The letters "p" and "n" stand for presentation and numeric. The presentation format for an address is often an ASCII string and the numeric format is the binary value that goes into a socket address structure.

#include <arpa/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr);
                                    Returns: 1 if OK, 0 if input not a valid presentation format, -1 on error
const char *inet_ntop(int  family,  const void *addrptr,  char *strptr,  size_t  len);
                                    Returns: pointer to result if OK, NULL on error

The first function tries to convert the string pointed to by strptr, storing the binary result through the pointer addrptr.

inet_ntop does the reverse conversion, from numeric (addrptr) to presentation (strptr).

Appendix:

Datatypes required by the POSIX specification.

   Datatype                                     Description                                                                Header

int8_t                          Signed 8-bit integer                                                                  <sys/types.h>

uint8_t                        Unsigned 8-bit integer                                                             <sys/types.h>

int16_t                         Signed 16-bit integer                                                               <sys/types.h>

uint16_t                      Unsigned 16-bit integer                                                           <sys/types.h>

int32_t                         Signed 32-bit integer                                                               <sys/types.h>

uint32_t                       Unsigned 32-bit integer                                                          <sys/types.h>

sa_family_t                Address family of socket address structure                        <sys/socket.h>

sa_family_t                Length of socket address structure,normally uint32_t      <sys/socket.h>


in_addr_t                   IPv4 address, normally uint32_t                                             <netinet/in.h>

in_port_t                   TCP or UDP port, normally uint16_t                                        <netinet/in.h>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值