Saturday, October 22, 2011

TCP/IP Study SUMMARY

1. The main protocols in the TCP/IP suite are the Internet Protocol (IP), the Transmission Control Protocol (TCP), and the User Datagram Protocol (UDP).
2. In TCP/IP, it takes two pieces of information to identify a particular program: an Internet address,used by IP, and a port number, the additional address interpreted by the transport protocol(TCP or UDP).
3. An IPv4 mapped address is formed by pre-fixing the four bytes in the IPv4 address with ::fff
4. Port numbers are the same in both IPv4 and IPv6: 16-bit unsigned binary numbers. Thus, each one is in the range 1 to 65,535 (0 is reserved).
5. A socket allows an application to plug in to the network and communicate with other applications that are plugged in to the same network.
6. socket addresses for the Internet protocol family have two parts: a 32-bit (IPv4) or 128-bit (IPv6) Internet address and a 16-bit port number.


Useful Function

| int socket(int domain, int type, int protocol)

| int close(int socket)

| Generic Addresses:
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
};

| For IPv4, use the sockaddr_in structure.
struct sockaddr_in {
sa_family_t sin_family
in_port_t sin_port;
struct in_addr sin_addr
char sin_zero[8];
};
For IPv6, use the sockaddr_in6 structure.
struct sockaddr_in6 {
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};

As with sockaddr_in, we must cast (a pointer to) the sockaddr_in6 to (a pointer to) a sockaddr in order to pass it to the various socket functions.

| In particular, what if we want to allocate an address structure, but we don’t know the actual address type (e.g.,IPv4 or IPv6)? The generic sockaddr won’t work because it’s too small for some address structures. To solve this problem, the socket designers created the sockaddr_storage structure,which is guaranteed to be as large as any supported address type.

| int inet_pton(int addressFamily, const char *src, void *dst)

| const char *inet_ntop(int addressFamily, const void *src, char *dst, socklen_t dstBytes)

| int getpeername(int socket, struct sockaddr *remoteAddress, socklen_t *addressLength)
int getsockname(int socket, struct sockaddr *localAddress, socklen_t *addressLength)
// getsockname() for the local address and getpeername() for the foreign address.

| int connect(int socket, const struct sockaddr *foreignAddress, socklen_t addressLength)

| int bind(int socket, struct sockaddr *localAddress, socklen_t addressSize)

| int listen(int socket, int queueLimit)

| int accept(int socket, struct sockaddr *clientAddress, socklen_t *addressLength)

| ssize_t send(int socket, const void *msg, size_t msgLength, int flags)

| ssize_t recv(int socket, void *rcvBuffer, size_t bufferLength, int flags)

| int getaddrinfo (const char *hostStr, const char *serviceStr, const struct addrinfo *hints, struct addrinfo **results)

//hostStr=NULL

//-std=c99 is different from -std=gnu99

| void freeaddrinfo(struct addrinfo *addrList)

UDP

1. There is no guarantee that a message sent via a UDP socket will arrive at its destination. This means that a program using UDP sockets must be prepared to deal with loss and reordering of messages;

2. it does not call connect(); it uses sendto() and recvfrom() instead of send() and recv();

| ssize_t sendto(int socket, const void *msg, size_t msgLength, int flags,
const struct sockaddr *destAddr, socklen_t addrLen)

| ssize_t recvfrom(int socket, void *msg, size_t msgLength, int flags,
struct sockaddr *srcAddr, socklen_t *addrLen)

// Two errors often made by novices are (1) passing an integer value instead of
a pointer to an integer for addrLen and (2) forgetting to initialize the pointed-to length variable to contain the appropriate size.

//Between the time a message arrives from the network and the time its data is returned via recv() or recvfrom(), the data is stored in a first-in, first-out (FIFO) receive buffer.

//The maximum amount of data that can ever be returned by recvfrom() on a UDP socket is 65,507 bytes—the largest payload that can be carried in a UDP datagram.

// Note that connecting and then using send() and recv() with UDP does not change how UDP behaves. Message boundaries are still preserved,

Sending and Receiving Data

// A way of encoding multibyte integers for transmission over a stream (TCP) socket is to use the built-in FILE-stream facilities

| FILE *fdopen(int socketdes, const char *mode)
int fclose(FILE * stream)
int fflush(FILE * stream)
size_t fwrite(const void * ptr, size_t size, size_t nmemb, FILE * stream)
size_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream)

// htonll() is a function that converts 64-bit integers from host to network byte order

// ntohll() is a network-to-host byte order converter for 64-bit types

// C language rules for laying out data structures include specific alignment requirements

Data structures are maximally aligned. That is, the address of any instance of a structure
(including one in an array) will be divisible by the size of its largest native integer field.
Fields whose type is a multibyte integer type are aligned to their size (in bytes). Thus,
an int32_t integer field’s beginning address is always divisible by four, and a uint16_t
integer field’s address is guaranteed to be divisible by two.

No comments:

Post a Comment