23
Programming Programming Part 2: Elementary Part 2: Elementary Sockets Sockets 8.5.2005 Jani Peusaari

Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

  • View
    225

  • Download
    7

Embed Size (px)

Citation preview

Page 1: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Unix Network ProgrammingUnix Network ProgrammingPart 2: Elementary SocketsPart 2: Elementary Sockets

8.5.2005 Jani Peusaari

Page 2: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

ContentsContents

Socket address structuresByte Ordering & ManipulationStreams

Necessary information on how to create a socket and how they work. Protocol dependency issues and introduction to performance.

Page 3: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

NotesNotes

In the book:– {} means a structure, e.g. in_addr{}– Solid boxes demonstrate system functions– Boxes with dashed lines demonstate authors

own functions

’const’ pointers as function arguments mean their contents are not changed in the function

Page 4: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Socket address structuresSocket address structures

Socket functions work through a reference to a protocol dependent address structure (sockaddr_ + protocol suffix)

Structures are used to pass information between the process and the kernel

Structures reside only on a given host, and are not passed in actual communication

Page 5: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

struct in_addr {in_addr_t s_addr;

};

struct sockaddr_in {uint8_t sin_len;sa_family_t sin_family; // AF_INETin_port_t sin_port;struct in_addr sin_addr;char sin_zero

};

Page 6: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Structure differencesStructure differences

POSIX only requires sin_family, sin_addr and sin_port

A POSIX compliant implementation may have additional fields

Almost all have implementations have a sin_zero field so that structures are at least 16 bytes (128 bits) long

Page 7: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

TypesTypes

POSIX defines different variable types that are used to define structures, to make architecture independent representations

Integer format: <signed?>int<bits>_te.g. uint8_t, int16_t

For backward compatibility reasons, some structure members can be other structures, that are again typedef’d as e.g. uint32_t

Also u_char, u_long for backward reasons

Page 8: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Different Protocol SupportDifferent Protocol Support

All socket functions must be usable with different protocol families

Socket address structures are of different size Solution: Generic socket address structure All functions require that structures are cast into a

pointer to this generic structure, e.g.:

bind(sockfd, (struct sockaddr *)serv, sizeof(serv)) Kernel checks protocol family

Page 9: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

From IPv4 to IPv6From IPv4 to IPv6

SIN6_LEN constant defined if sin6_len field present in socket address structure

Family is AF_INET6 (In IPv4 AF_INET)Structure designed to be 64-bit alignedNew generic socket address structure

defined: struct sockaddr_storage

Page 10: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

struct in6_addr {uint8_t s6_addr[16];

};

struct sockaddr_in {uint8_t sin6_len;sa_family_t sin6_family; // AF_INET6in_port_t sin6_port;uint32_t sin6_flowinfo;struct in6_addr sin6_addr;uint32_t sin6_scope_id;

};

Page 11: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

New Generic Socket Address New Generic Socket Address StructureStructure

The old one only 16 bytes longNew one is defined to be as long as the

largest possible structure in the systemSupport for alignment requirements

If things were designed now, all would be cast as (void *), length field would be a requirement...

Page 12: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Value-Result ArgumentsValue-Result Arguments

Socket Address Structures are commonly passed as a reference

Some arguments used in two waysE.g. int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

*addrlen is a value when called, result when function returns (especially for variable length socket address structures)

Page 13: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Byte OrderingByte Ordering

Systems use different byte orders, known as little-endian and big-endian

Network byte order, host byte orderNetwork byte order is big-endianPOSIX requires that certain fields in socket

address structures must be maintained in network byte order

User is responsible for this

Page 14: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Byte ordering functionsByte ordering functions

Host to Network functions

uint16_t htons(uint16_t host16bitvalue);

uint32_t htonl(uint32_t host32bitvalue);Network to Host functions

uint16_t ntohs(uint16_t net16bitvalue);

uint32_t ntohl(uint32_t net32bitvalue);

Page 15: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Address/ASCII conversionAddress/ASCII conversion

Functions that convert from/to ASCII strings to/from network byte ordered binary valuesE.g. ”157.24.8.133” to 32-bit network byte ordered binary value

ASCII / Network (inet_aton, inet_ntoa)Presentation / Numeric (inet_pton,

inet_ntop)

Page 16: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

#include <arpa/inet.h>

int inet_aton(const char *strptr, struct in_addr *addrptr);

in_addr_t inet_addr(const char *strptr);

// DONT USE

char *inet_ntoa(struct in_addr inaddr);

Page 17: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

#include <arpa/inet.h>

int inet_pton(int family, const char *strptr, void *addrptr);

const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);

Page 18: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

ProblemsProblems

Older functions only work with IPv4, and have some special qualities

E.g. what inet_addr returns on errorNewer functions require that we know the

address family– Family as argument– Structure member names

Page 19: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

StreamsStreams

File reading functions, e.g. read/write are also used with stream sockets

Unlike with files, these functions may return less bytes read/written than requested, but it is not an error

The book demonstrates functions, which correctly handle stream sockets

Page 20: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Solutions presentedSolutions presented

The book shows sock_* functions, an approach for family independent code

Instead of calling e.g. inet_ntop directly, call a matching sock_ntop function, which looks inside the socket address structure for family, and call inet_ntop accordingly

Approach that simplifies portability between families

Page 21: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Supporting functionsSupporting functions

Functions that operate on multibyte data, without interpreting the data, without assuming null terminates the data

4.2BSD (b*) and ANSI C (mem*) functionsNeeded for zeroying socket address

structures, copying structures / structure members

Page 22: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

#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);

#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);

Page 23: Unix Network Programming Part 2: Elementary Sockets 8.5.2005 Jani Peusaari

Portable codePortable code

Compile time tests to check socket address structures

Always check socket address structure size (e.g. sizeof(sockaddr_in))

Use newer inet_* functions that support both IPv4 and IPv6 addresses– Possibly with wrappers to handle address

families in an independent way