Introduction to "UNIX Network programming" socket programming

Source: Internet
Author: User

IPV4 Socket Address Structure:

It is also commonly used as an "internetwork socket address Structure", named after the sockaddr_in, and defined in the <netinet/in.h> header file.

struct in_addr  {    in_addr_t s_addr; 32bits IP address, such as 0xff000001-127.0.0.1  };
/* Structure describing an Internet socket address.  */struct sockaddr_in  {    uint8_t sin_len;   /* Length of structure (+) */    sa_family_t sin_family; /* af_inet */    in_port_t sin_port;/* port number. 16bits */    struct in_addr sin_addr;/* Internet address.  */    char sin_zero[8];           /* Unused */  };  SIN_FAMILY,SIN_PORT,SIN_ADDR is a certain 3 member of the support

IPV4 addresses and TCP or UDP port numbers are always stored in the socket address structure in a network byte order (distinguished from host byte order).

The reason is that the Internet address (in_addr) is a struct, because previously this struct allows access to 2 16-bit values for partitioning a, B, Class C, and now after subnetting, these union structures are no longer needed.

The Sin_zero field was never used, but we always set the field to 0, and by convention we always set the entire structure to 0before filling it out.

--------------------------Split Line---------------------------------

The above is the IPV4 socket address structure, however the socket function is generic and always receives a pointer to a socket address structure (eg, sockaddr_in serv; bind (SOCKFD, (sockaddr *) &serv, sizeof (serv)); ), you can see that the second parameter is turned into the sockaddr type, which is the universal socket address structure . In the socket function definition, there is no universal pointer type void *, so you must pass in an appropriate type, otherwise it will be an error, so in <sys/socket.h> defines a generic socket address structure.

A universal socket address structure is used to perform a type cast on a pointer to a protocol-specific socket address structure .

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

--------------------------Split Line---------------------------------

The IPV6 address is 128 bits long, but it is usually written in 8 groups, each set of four hexadecimal digits, such as fe80:0000:0000:0000:aaaa:0000:00c2:0002.

The IPv6 socket address structure is defined in the <netinet/in.h> header file:

struct IN6_ADDR  {uint8_ts6_addr[16];  };       #define SIN6_LENSTRUCT sockaddr_in6  {    uint8_t sin6_len;   /* Length of this struct (sa_family_t) */    sin6_family; /* AF_INET6 */    in_port_t sin6_port;/* Transport Layer Port # */    uint32_t sin6_flowinfo;/* IPv6 Flow information */    struct IN6_ADDR sin6_addr;/* IPv6 address */    uint32_t sin6_scope_id;/* IPv6 Scope-id */  };

If the system supports length fields in the socket address structure, then the Sin6_len constant must be defined.

The address family of IPV6 is Af_inet6, and IPv4 's address family is af_inet.

The order of the fields in the structure is arranged so that if the SOCKADDR_IN6 structure itself is 64-bit aligned, the 128-bit SIN6_ADDR field is also 64-bit aligned. On some 64-bit processing machines, if the 64-bit data is stored in a 64-bit boundary location, the access to it will be optimized.

The Sin6_flowinfo field is divided into two fields: the low-order 20-bit is stream (flow label), high-order 12-bit reserved.

For a range of addresses (scoped address), the SIN6_SCOPE_ID field identifies its scope (scope), most commonly the interface index (interface index) of the link local address (link-local addresses)

--------------------------Split Line---------------------------------

New Universal socket Address structure: The new structure overcomes some of the drawbacks of sockaddr, and the new sockaddr_storage is sufficient to accommodate any socket address structure supported by the system.

struct Sockaddr_storage {  uint8_t   Ss_len;   /* Length of this struct (implementation dependent) */  sa_family_t  ss_family;    /* Address family:af_xxx value *  /* implementation-dependent elements to provide:   * a) alignment sufficient to F Ulfill The alignment requirements of   * All sockets address types that the system supports.   * b) enough storage to hold any type of socket address, that the   * system supports.   */};

The Sockaddr_storage is able to meet the most demanding alignment requirements.

Sockaddr_storage is large enough to accommodate any socket address structure supported by the system, except for ss_family and Ss_len (if any), other fields can be placed arbitrarily (transparent to the user), and the sockaddr_storage structure must You can access other fields by casting or copying to the socket address structure that is appropriate for the address type given by the Ss_family field .

--------------------------Split Line---------------------------------

value-Result parameter (said is the passed parameter as the return result of the reference, eg, func (&res)):

When passing a socket address structure to a socket function, the structure is always passed as a reference , that is, a pointer to the struct is passed. The length of the structure is also passed as a parameter, but the way it is passed depends on the direction in which the structure is passed: from the kernel of the process, from the kernel to the process.

1) There are 3 functions to pass the socket address structure from the process to the kernel: Bind, connect, sendto. One parameter to these functions is a pointer to a socket address structure, and the other parameter is the integer size of the structure. (The kernel needs to know exactly how much data has been copied from the process)

2) There are 4 functions for passing a socket address structure from the kernel to the process: Accept, recvfrom, GetSockName, and Getpeername. The two parameters of these 4 functions are pointers to a socket address structure and pointers to integer variables that represent the size of the structure (this is a result, so it is a reference pass value).

Value-Result parameter returns the result: if the socket address structure is fixed length (such as IPV4 (16) and IPV6 (28)), the return value is always fixed length, and for variable lengths (Unix domains, etc.), the return value may be less than the maximum length of the structure.

--------------------------Split Line---------------------------------

byte sort function

Small endian byte order (Little-endian): Low-order bytes are stored at the start address, such as 0x12345678, in memory from small to large addresses, the storage sequence is 78 56 34 12

Big endian byte order (Big-endian): High-order bytes are stored in the start address, such as 0x12345678, in memory from small to large address, storage sequence is 12 34 56 78

Both of these formats are system-used! We use the byte order of a given system as the host byte order (hosts byte order)

#include    ". /unpv13e/unp.h "#include    ". /unpv13e/apueerror.h "//above path is my own configuration//page.64 program that determines the host byte order (small-or big-endian alignment) Intmain (int argc, char **argv) {    Union {        Short  s;        Char   c[sizeof (short)];    } un;    UN.S = 0x0102;    printf ("%s:", cpu_vendor_os);  Output CPU type, manufacturer, and operating system version.    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", (int.) sizeof (short));    Exit (0);}

Question 1: What is the difference between network byte order and host byte order?

A: The Internet protocol uses big- endian byte-order to transmit these multibyte integers, while the host byte order used by the system may be big-endian or small-ended.

Question 2: What is the implementation method?

A: The fields of the socket address structure are maintained in the network byte order (big-endian), so the conversion is done through the function. (Below h:host,n:network,s:short->16bits port,l:long->32bits IPv4)

Htons returns the port of the network byte order

HTONL returns IP for network byte order

Ntohs returns the port of host byte order

Ntohl returns IP for host byte order

Note: In fact, in a 64-bit system, a long integer, while occupying 64 bits, is still a 32-bit value for the function operation to long.

In a system with a big endian byte sequence, these 4 functions are defined as empty macros.

BYTE manipulation functions

Functions that deal with strings are placed in string.h, but the multibyte field, like the socket address structure, needs to be cleared 0, and a byte manipulation function (with 2 groups) is required:

#include <strings.h>//Strings.h is inherited from the BSD Unix system, which defines some string functions, as referenced from http://blog.csdn.net/xin_yu_xin/article/ Details/38672137void bzero (void *dest, size_t nbytes), void bcopy (const void *src, void *dest, size_t nbytes); int bcmp (cons t void *ptr1, const void *PTR2, size_t nbytes);    0 is equal, not 0 is unequal
#include <string.h>//ANSI C standard 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);    0 is the same, not 0 is not the same

To do a test, using memset, the value of C is set to 1, for an int type of the number, get a relatively large result, 16843009, so looked up an article found. It is proved that memset is populated according to bytes , so in fact after memset, the value is 0x01010101, that is 16843009 (Ten), StackOverflow also have a same problem answer.

--------------------------Split Line---------------------------------

Address Translation functions

Function: Convert from dotted decimal string (e.g.: 206.168.112.96) to network byte-order binary value

Two sets of functions:

(1) Inet_aton, inet_addr, Inet_ntoa (for IPV4 only)

#include <arpa/inet.h>int inet_aton (const char *strptr, struct in_addr *addrptr);     Returns 1 if the string is valid, otherwise 0. If the addrptr pointer is empty, the function still performs a validity check on the input string, but does not store any results in_addr_t inet_addr (const char *strptr);    String is valid returns the IPV4 address of the 32-bit binary network byte order, otherwise returns Inaddr_none ( This is usually 255.255.255.255, which means that this limited broadcast address cannot be handled by this function, and another problem is that some compiler-compiled programs will return 1 results instead of inaddr_none, so this function is now obsolete, with inet_ Aton or Inet_pton to replace) char *inet_ntoa (struct in_addr inaddr); Note that the parameter is a struct rather than a struct pointer (which is very rare), the return value is a pointer to a dotted decimal string, and the function's return value points to a string that resides in static memory, assuming that the function is non-reentrant (the following concept)

     reentrant functions: reentrant functions are mainly used in multitasking environments, a reentrant function is simply a function that can be interrupted, re-entry can be understood as repeated access, that is, you can break it at any moment of execution of this function, go to the OS Scheduler to execute another piece of code, There is no error in returning the control, and the non-reentrant function can be problematic if it is interrupted because it uses some system resources, such as the global variable area, the interrupt vector table, and so on, which cannot be run in a multi-tasking environment.

(2) Inet_pton, Inet_ntop (for both IPV4 and IPV6) p for presentation (expression) n for numeric (value)

#include <arpa/inet.h>int inet_pton (int family, const char *strptr, void *addrptr),//Success returns 1, input not valid expression format returns 0, Error returns -1const char *inet_ntop (int family, const void *addrptr, char *strptr, size_t len);//Success Returns a pointer to the result, error returning Null,len is the Target store order The size of the meta, which is used to prevent buffer overflow, in order to help specify this size, defined in the <netinet/in.h> header file//#define     Inet_addrstrlen     16//#define     INET6 _addrstrlen    46//If Len is too small to accommodate the result of the expression format (including the trailing null character), a null pointer is returned, the errno is a enospc,strptr parameter cannot be a null pointer, the size must first be allocated, the call succeeds, This pointer is the return value of the function.

Only simple definitions of the Inet_pton and inet_ntop functions of IPV4 are supported:

Intinet_pton (int family, const char *strptr, void *addrptr) {    if (family = = af_inet) {    struct in_addr  in_val;< C3/>if (Inet_aton (StrPtr, &in_val)) {            memcpy (addrptr, &in_val, sizeof (struct in_addr));            return (1);        } return (0);    } errno = Eafnosupport;    Return (-1);}
const char *inet_ntop (int family, const void *addrptr, char *strptr, size_t len) {const U_CHAR *p = (const U_CHAR *) ADDRPT R;if (Family = = af_inet) {chartemp[inet_addrstrlen];snprintf (temp, sizeof (temp), "%d.%d.%d.%d", P[0], p[1], p[2], p[3]); if (strlen (temp) >= len) {errno = Enospc;return (NULL);} strcpy (StrPtr, temp); return (STRPTR);} errno = Eafnosupport;return (NULL);}

There are also UNP self-defined functions, chap 3.8 (page 70~72), which are no longer described here.

Read and write functions (to be written page 72)

Introduction to "UNIX Network programming" socket programming

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.