All notes

OSI layer models

OSI: Open System Interconnection. MTU: maximum transmission unit.

From lower to higher:

  1. Physical layer. It is concerned with the transmission and reception of the unstructured raw bit stream over a physical medium.
    twisted pair, coaxial cable, optical fiber, wireless.
    Ethernet, DSL, Bluetooth, USB.
  2. Data link layer. It provides (virtually) error-free transfer of data frames from one node to another over the physical layer.
    It is divided into two sub layers:
    • MAC, media access control, controls how a computer on the network gains access to the data and permission to transmit it.
    • LLC, Logical link control, controls frame synchronization, flow control and error checking. Provides multiplexing mechanisms that make it possible for several network protocols such as IP, IPX, Decnet and Appletalk to coexist within a multipoint network and to be transported over the same network medium.
    Includes: ARP, L2TP, PPP, IEEE 802.5/ 802.2, IEEE 802.3/802.2.
  3. Network layer: it takes all routing decisions, dealing with end to end data transmission, such as the operation of the subnet, deciding which physical path the data should take based on network conditions, priority of service, and other factors.
    IP, IPsec, ICMP, AppleTalk.
  4. Transport layer: TCP, UDP, SPX.
  5. Session layer: controls the dialogues (connections) between computers.
    NFS, RPC, SOCKS, PPTP, SPDY, NetBIOS, Named pipe.
  6. Presentation layer: defines and encrypts/decrypts data types from the application layer.
    MIME, XDR, MPEG, GIF, .etc.
  7. Application layer: keeps track of how each application talks to another application.
    HTTP, DHCP, Gopher, DNS.

Data link Layer, L2


The Address Resolution Protocol (ARP) is a telecommunication protocol used for resolution of network layer addresses into link layer addresses, a critical function in multiple-access networks.


MAC layer is the lower sublayer of the data link layer (layer 2) of the seven-layer OSI model. The MAC sublayer provides addressing and channel access control mechanisms that make it possible for several terminals or network nodes to communicate within a multiple access network that incorporates a shared medium, e.g. an Ethernet network. The hardware that implements the MAC is referred to as a media access controller.

Network Layer, L3


AppleTalk was a proprietary suite of networking protocols developed by Apple Inc. for their Macintosh computers. AppleTalk includes a number of features that allow local area networks to be connected with no prior setup or the need for a centralized router or server of any sort. Connected AppleTalk-equipped systems automatically assign addresses, update the distributed namespace, and configure any required inter-networking routing. It is a plug-n-play system.

Session Layer, L4



Class A B C

什么是A类、B类、C类地址? IP地址有三种基本类型,由网络号的第一组数字来表示。 A类地址的第一组数字为1~126。注意,数字0和 127不作为A类地址,数字127保留给内部回送函数,而数字0则表示该地址是本地宿主机,不能传送。 B类地址的第一组数字为128~191。 C类地址的第一组数字为192~223。 例如:我校的网络号是202.206.64--79 , 它的第一组数字为202,因此202.206.64.34是C类地址。而159.266.1.1则是B类地址。 目前IP地址资源较紧张,向INTERNET亚太中心能申请到的大多是C类地址。 Internet管理委员会规定如下地址段为私有地址,私有地址可以自己组网时用,但不能在Internet网上用,Internet网没有这些地址 的路由,有这些地址的计算机要上网必须转换成为合法的IP地址,也称为公网地址。 下面是A、B、C类网络中的私有地址段。你自己组网时就可以用这些地址了。 广播地址 TCP/IP规定,主机号全为"1"的网络地址用于广播之用,叫做广播地址。


一个255是8位: $2^7+...+2^0 = 2^8-1$ / 24 / 16 / 20. $240/2~0 120/2~0 60/2~0 30/2~0 15/2~1 7/2~1 3/2~1 1/2~1$









BGP(Border Gateway Protocol,边界网关协议)主要用于互联网AS(自治系统)之间的互联,BGP的最主要功能在于控制路由的传播和选择最好的路由。BGP是Internet工程任务组制定的一个加强的、完善的、可伸缩的协议。采用BGP方案来实现双线路互联或多线路互联的机房,称为BGP机房。

中国网通 、中国电信、中国铁通和一些大的民营IDC运营商都具有AS号,全国各大网络运营商多数都是通过BGP协议与自身的AS号来实现多线互联的。使用此方案来实现多线路互联,IDC需要在CNNIC(中国互联网信息中心)或APNIC(亚太网络信息中心)申请自己的IP地址段和AS号,(特别注明:目前国内的世纪互联同时是APNIC和CNNIC的会员单位,号称中国最大的电信中立互联网基础设施服务商),然后通过BGP协议将此段IP地址广播到其它的网络运营商的网络中。使用BGP协议互联后,网络运营商的所有骨干路由设备将会判断到IDC机房IP段的互联最佳路由,以保证不同网络运营商用户的高速访问。

Wikipedia: BGP.

Border Gateway Protocol (BGP) is a standardized exterior gateway protocol designed to exchange routing and reachability information among autonomous systems (AS) on the Internet. It belongs to Application Layer.

The protocol is often classified as a path vector protocol but is sometimes also classed as a distance-vector routing protocol. The Border Gateway Protocol makes routing decisions based on paths, network policies, or rule-sets configured by a network administrator and is involved in making core routing decisions.

BGP may be used for routing within an autonomous system. In this application it is referred to as Interior Border Gateway Protocol, Internal BGP, or iBGP.

The current version of BGP is version 4 (BGP4 or BGP-4) codified in RFC 4271 since 2006. The major enhancement in version 4 was support for Classless Inter-Domain Routing and use of route aggregation to decrease the size of routing tables.

Most Internet service providers must use BGP to establish routing between one another (especially if they are multihomed).


# Increase local port range by typing the following command (Linux specific example):
echo 1024 65535 > /proc/sys/net/ipv4/ip_local_port_range

# You can also increase or decrease socket timeout (Linux specific example):
echo 2000 > /proc/sys/net/ipv4/tcp_keepalive_time


TTL is the short name for Time to live. It usually appears in IP packets, DNS records or HTTP, with a little difference among them.

IP packets

TTL is an 8-bit field under Internet Protocal (IP), and thus its maximum is 255. Under IPv6, it is renamed hop limit. Everytime the IP packet is transfered by a router, its TTL value is decreased by 1, and when it comes down to 0, it will be discarded and an ICMP error - Time Exceeded - is sent back to the sender. Obviously, TTL here is used to kill those immortals and keep our internet clean. Wikipedia page says TTL is in theory measured by seconds, but here in practice it is measured by hop times, thus the name in IPv6.

DNS records

TTLs also occur in the DNS, where each item in the zone file has a TTL. When a cache/recursive nameserver fetches a resource record from an authoritative nameserver, it will cache the record for the time specified by its TTL (measured in seconds). Shorter TTL in zone file imposes heavier loads on an authoritative nameserver, but is useful when changing the critical address. The recommended practice is to lower it down before changing these addresses. Some cache nameservers do not respect the TTL set in authoritative nameservers, therefore it is not guaranteed that all downstream DNS records are renewed after the TTL has expired.


TTLs are also present in headers in HTTP responses, and field in HTTP cookies. Their significance is similar as previously mentioned.

SSL certificate

  1. Generate a new CSR (Certificate Signing Request). Now Godaddy asks for more than 2048-bit and SHA-2.
  2. Re-key your certificate.

Generate a CSR

Godaddy: generate CSR.

  1. First generate and submit a Certificate Signing Request (CSR) to the Certification Authority (CA).
  2. The CSR contains your certificate-application information, including your public key.
  3. Use your Web server software to generate the CSR, which will also create your public/private key pair used for encrypting and decrypting secure transactions.

DN asked for CSR

The Web server software will use this information to create your Web server certificate's distinguished name (DN). Distinguished names uniquely identify individual servers:

About DBA. Doing Business As (DBA): The operating name of a company, as opposed to the legal name of the company. See Entrepreneur webpage, and this good article for reference.

Install SSL cert on Apache

Godaddy tutorial.

Use apachectl graceful to restart.

Use GlobalSign page to test whether SSL certificate is installed successfully.

Re-keying SSL cert

Re-keying is the process of generating a new private key for your existing SSL certificate. Your Web server uses the private key to decrypt secure information.

The information in your new CSR must be identical to the information for your existing certificate, i.e. you cannot change the organization.

If you need to change your certificate details, you must revoke the certificate in your account, purchase a new SSL credit, and complete the SSL request again.

Network programming

See the server and client example in the last of the manual.

What is a socket

Ref. In layman’s term, a Socket is an end point of communication between two systems on a network. To be a bit precise, a socket is a combination of IP address and port on one system. So on each system a socket exists for a process interacting with the socket on other system over the network. A combination of local socket and the socket at the remote system is also known a ‘Four tuple’ or ’4-tuple’. Each connection between two processes running at different systems can be uniquely identified through their 4-tuple.

Client example

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define BUF_SIZE 500

int main(int argc, char *argv[])
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int sfd, s, j;
    size_t len;
    ssize_t nread;
    char buf[BUF_SIZE];

    if (argc < 3) {
        fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);

    /* Obtain address(es) matching host/port */
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = 0;
    hints.ai_protocol = 0;          /* Any protocol */

    s = getaddrinfo(argv[1], argv[2], &hints, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));

   /* getaddrinfo() returns a list of address structures.
       Try each address until we successfully connect(2).
       If socket(2) (or connect(2)) fails, we (close the socket
       and) try the next address. */

   for (rp = result; rp != NULL; rp = rp->ai_next) {
        sfd = socket(rp->ai_family, rp->ai_socktype,
        if (sfd == -1)

       if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
            break;                  /* Success */


   if (rp == NULL) {               /* No address succeeded */
        fprintf(stderr, "Could not connect\n");

   freeaddrinfo(result);           /* No longer needed */

   /* Send remaining command-line arguments as separate
       datagrams, and read responses from server */

   for (j = 3; j < argc; j++) {
        len = strlen(argv[j]) + 1;
                /* +1 for terminating null byte */

       if (len + 1 > BUF_SIZE) {
                    "Ignoring long message in argument %d\n", j);

       if (write(sfd, argv[j], len) != len) {
            fprintf(stderr, "partial/failed write\n");

       nread = read(sfd, buf, BUF_SIZE);
        if (nread == -1) {

       printf("Received %ld bytes: %s\n", (long) nread, buf);


htonl, htons, ntohl, ntohs

Ref. Convert values between host and network byte order.

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);



Hints usually have ai_family, ai_socktype, ai_protocol, ai_flags set, while other fields set to 0.

If the AI_PASSIVE flag is specified in hints.ai_flags, and node is NULL, then the returned socket addresses will be suitable for binding a socket that will accept connections. The returned socket address will contain the "wildcard address" (INADDR_ANY for IPv4 addresses, IN6ADDR_ANY_INIT for IPv6 address). The wildcard address is used by applications (typically servers) that intend to accept connections on any of the hosts's network addresses. If node is not NULL, then the AI_PASSIVE flag is ignored.



// prints 0, which means

// in inet.h, it shows:

# define INADDR_ANY ((unsigned long int) 0x00000000)
# define INADDR_NONE    0xffffffff
# define INPORT_ANY 0

// While INADDR_LOOPBACK means

If the AI_PASSIVE flag is not set in hints.ai_flags, then the returned socket addresses will be suitable for use with connect(2), sendto(2), or sendmsg(2). If node is NULL, then the network address will be set to the loopback interface address (INADDR_LOOPBACK for IPv4 addresses, IN6ADDR_LOOPBACK_INIT for IPv6 address); this is used by applications that intend to communicate with peers running on the same host.

service sets the port in each returned address structure. If this argument is a service name, it is translated to the corresponding port number. This argument can also be specified as a decimal number, which is simply converted to binary. If service is NULL, then the port number of the returned socket addresses will be left uninitialized. If AI_NUMERICSERV is specified in hints.ai_flags and service is not NULL, then service must point to a string containing a numeric port number. This flag is used to inhibit the invocation of a name resolution service in cases where it is known not to be required.

Either node or service, but not both, may be NULL.

The getaddrinfo() function allocates and initializes a linked list of addrinfo structures, one for each network address that matches node and service, subject to any restrictions imposed by hints, and returns a pointer to the start of the list in res. The items in the linked list are linked by the ai_next field.

There are several reasons why the linked list may have more than one addrinfo structure, including: the network host is multihomed, accessible over multiple protocols (e.g., both AF_INET and AF_INET6); or the same service is available from multiple socket types (one SOCK_STREAM address and another SOCK_DGRAM address, for example). Normally, the application should try using the addresses in the order in which they are returned. The sorting function used within getaddrinfo() is defined in RFC 3484; the order can be tweaked for a particular system by editing /etc/gai.conf (available since glibc 2.5).

If hints.ai_flags includes the AI_CANONNAME flag, then the ai_canonname field of the first of the addrinfo structures in the returned list is set to point to the official name of the host.

// Reference.

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
@retval 0 success.
@retval non-0 error. Use gai_strerror() to translate it.
int getaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res);

void freeaddrinfo(struct addrinfo *res);

const char *gai_strerror(int errcode);

struct addrinfo {
	int              ai_flags;
	int              ai_family;
	int              ai_socktype; // SOCK_STREAM, SOCK_DGRAM.
	int              ai_protocol;
	socklen_t        ai_addrlen;
	struct sockaddr *ai_addr;
	char            *ai_canonname;
	struct addrinfo *ai_next;

Reference: stackoverflow. The reason why we could cast pointers of the other structures to sockaddr*, is because most functions only need the sa_family, and it is 16bit in all those structures.

struct sockaddr {
	unsigned short    sa_family;    // address family, AF_xxx
	char              sa_data[14];  // 14 bytes of protocol address

// In Mac OS, sys/socket.h, we have a different one.
struct sockaddr {
	__uint8_t	sa_len;		/* total length */
	sa_family_t	sa_family;	/* [XSI] address family */
	char		sa_data[14];	/* [XSI] addr value (actually larger) */

// Defined in "/usr/include/netinet/in.h".
struct sockaddr_in {
	short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
    char             sin_zero[8];  // zero this if you want to

/* Internet address. */
// in_addr. Should be assigned one of the INADDR_* values (e.g., INADDR_ANY) or set using the inet_aton library functions or directly with the name resolver (see gethostbyname).
struct in_addr {
    uint32_t       s_addr;     /* address in network byte order */

// cp: Internet host address with the IPv4 numbers-and-dots notation.
// Stores it in the structure that inp points to.
// Returns nonzero if the address is valid, zero if not.
// The two functions are in /usr/include/arpa/inet.h
int inet_aton(const char *cp, struct in_addr *inp);
char *inet_ntoa(struct in_addr in);

struct sockaddr_in6 {
    u_int16_t       sin6_family;   // address family, AF_INET6
    u_int16_t       sin6_port;     // port number, Network Byte Order
    u_int32_t       sin6_flowinfo; // IPv6 flow information
    struct in6_addr sin6_addr;     // IPv6 address
    u_int32_t       sin6_scope_id; // Scope ID

struct sockaddr_storage {
    sa_family_t  ss_family;     // address family

    // all this is padding, implementation specific, ignore it:
    char      __ss_pad1[_SS_PAD1SIZE];
    int64_t   __ss_align;
    char      __ss_pad2[_SS_PAD2SIZE];


//SIGPIPE ignore                                                       
struct sigaction act;
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, 0);


The file descriptor tables

Each running process has a file descriptor table which contains pointers to all open i/o streams. When a process starts, three entries are created in the first three cells of the table. Entry 0 points to standard input, entry 1 points to standard output, and entry 2 points to standard error. Whenever a file or other i/o stream is opened, a new entry is created in this table, usually in the first available empty slot.

The socket system call returns an entry into this table; i.e. a small integer. This value is used for other calls which use this socket. The accept system call returns another entry into this table. The value returned by accept is used for reading and writing to that connection.

// Reference.

#include <sys/types.h>
#include <sys/socket.h>
	@brief Creates an endpoint for communication and returns a fd.

	@param[in]	domain	AF_INET (ipv4), AF_INET6.
	@param[in]	type	SOCK_STREAM (tcp), SOCK_DGRAM (UDP).
	@param[in]	protocol Usually 0.
int socket(int domain, int type, int protocol);



#include <sys/socket.h>

int setsockopt(int socket, int level, int option_name,
	const void *option_value, socklen_t option_len);

// Example. 
if (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
	perror("Create socket error");
	exit -1;

int flag=1;
// Set options at the socket level: SOL_SOCKET.
// Used to solve Error "address already in use" from bind().
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (void*)&flag, sizeof(int));

Bind Error: "Address already in use"

// Reference. When closing the socket, the kernel keeps it in TIME_WAIT state for about 2 to 4 minutes. "A socket is a 5 tuple (proto, local addr, local port, remote addr, remote port). SO_REUSEADDR just says that you can reuse local addresses. The 5 tuple still must be unique!"

shutdown, close

Reference. Sockets can be closed with close(fd). If there is still data waiting to be transmitted, close() will try to complete the transmission. The SO_LINGER socket option specifies a timeout period.

Another and more precise way is shutdown().

	@param[in] how
		0: Stop receiving data.
		1: Stop sending data.
		2: Stop both.

	@retval 0 success.
	@retval -1 error.
int shutdown(int socket, int how);
The errno cases include:


// Reference.

#include <sys/types.h>
#include <sys/socket.h>
	@brief Connect sockfd to the addr.

	Generally, connection-based protocol sockets may successfully
       connect() only once; connectionless protocol sockets may use
       connect() multiple times to change their association.

	@retval 0	Success.
	@retval -1	Error.

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);


Reference. getpeername() returns the address of the peer connected to the socket sockfd, in the buffer pointed to by addr.

#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

For stream sockets, once a connect(2) has been performed, either socket can call getpeername() to obtain the address of the peer socket.

On the other hand, datagram sockets are connectionless. Calling connect(2) on a datagram socket merely sets the peer address for outgoing datagrams sent with write(2) or recv(2). The caller of connect(2) can use getpeername() to obtain the peer address that it earlier set for the socket. However, the peer socket is unaware of this information, and calling getpeername() on the peer socket will return no useful information (unless a connect(2) call was also executed on the peer). Note also that the receiver of a datagram can obtain the address of the sender when using recvfrom(2).


Explanations are given in the code comments.

// Reference.

#include <sys/types.h>
#include <sys/socket.h>

/** @brief Receive contents.

	Receive contents from either connection-based/-less sockets.

	If no message are available at the socket, the calls wait for a
	message to arrive, unless the socket is nonblocking, in which case
	-1 is returned (and errno is set to EAGAIN

	An application can use select, poll,
	or epoll to determine when more data arrives on a

	@retval	-1, or the length of the received message in bytes.

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct
	sockaddr *src_addr, socklen_t *addrlen);

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);


CompGroups. These two errorno no are different integers, but may indicate similar errors:

Ref: why epoll is better than poll and select.


// Reference.

/** @brief Synchronous I/O multiplexing.

	select() and pselect() are used to monitor
	multiple file descriptors, waiting until one or more of them become

	@param[in] nfds Number of FDs. It's the highest-numbered file
		descriptor in any of the three sets, plus 1.

	@param[in] timeout The argument specifies the interval that
		select() should block waiting for a file descriptor to become

	@note on timeout
		If both fields of the timeval structure are zero, then select()
		returns immediately. (This is useful for polling.) If timeout is
		NULL (no timeout), select() can block indefinitely.

	@retval Number of FDs contained in the three returned sets. -1 is
		returned on error.


////////// - select --

/* According to POSIX.1-2001 */
#include <sys/select.h>

/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>	
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set
           *exceptfds, struct timeval *timeout);

/** @brief Four macros provided to manipulate the File Description sets.

// Remove fd from set.
void FD_CLR(int fd, fd_set *set);
// Add fd to set.
void FD_SET(int fd, fd_set *set);
// Check if fd is in set.
int  FD_ISSET(int fd, fd_set *set);
// Clear set.
void FD_ZERO(fd_set *set);

////////// - pselect --
#include <sys/select.h>

Linux specific.
int pselect(int nfds, fd_set *readfds, fd_set *writefds,
            fd_set *exceptfds, const struct timespec *timeout,
            const sigset_t *sigmask);

// Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
// pselect(): _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600


// Reference.

#include <poll.h>

struct pollfd
	int fd;         /* file descriptor */
	short events;     /* requested events */
	short revents;    /* returned events */

	@brief poll performs a similar task
	to select: waits for one of a set of file descriptors
	to become ready to perform I/O.

	Specifying a negative value in timeout means an infinite timeout.
	Specifying a timeout of zero causes poll() to return immediately.

	@retval 0: the call timed out and no FD was ready.
	@retval -1: error.
	@retval positive number: number of structures having non-zero revents.


int poll(struct pollfd *fds, nfds_t nfds, int timeout);

////////// Seperator

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <signal.h>
#include <poll.h>

Linux specific.
int ppoll(struct pollfd *fds, nfds_t nfds,
        const struct timespec *timeout_ts, const sigset_t *sigmask);



This overflow discussion is a good reference. accept() is a blocking call, and the CPU is allowed to execute other threads after calling it. Once the accept() is returned, the CPU comes back to execute the following steps.


#include <sys/types.h>
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

The accept() system call is used with connection-based socket types (SOCK_STREAM, SOCK_SEQPACKET). It extracts the first connection request on the queue of pending connections for the listening socket, sockfd, creates a new connected socket, and returns a new file descriptor referring to that socket. The newly created socket is not in the listening state. The original socket sockfd is unaffected by this call.

The argument sockfd is a socket that has been created with socket(2), bound to a local address with bind(2), and is listening for connections after a listen(2).

If no pending connections are present on the queue, and the socket is not marked as nonblocking, accept() blocks the caller until a connection is present. If the socket is marked nonblocking and no pending connections are present on the queue, accept() fails with the error EAGAIN or EWOULDBLOCK.

In order to be notified of incoming connections on a socket, you can use select(2) or poll(2). A readable event will be delivered when a new connection is attempted and you may then call accept() to get a socket for that connection. Alternatively, you can set the socket to deliver SIGIO when activity occurs on a socket; see socket(7) for details.

The following code snippet comes from this page.

int setNonblocking(int fd)
    int flags;

    /* If they have O_NONBLOCK, use the Posix way to do it */
#if defined(O_NONBLOCK)
    /* Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. */
    if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
        flags = 0;
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    /* Otherwise, use the old way of doing it */
    flags = 1;
    return ioctl(fd, FIOBIO, &flags);



#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
		const struct sockaddr *dest_addr, socklen_t addrlen);

The send() call may be used only when the socket is in a connected state (so that the intended recipient is known). The only difference between send() and write(2) is the presence of flags. With a zero flags argument, send() is equivalent to write(2). Also, the following call send(sockfd, buf, len, flags); is equivalent to sendto(sockfd, buf, len, flags, NULL, 0);

If the message is too long to pass atomically through the underlying protocol, the error EMSGSIZE is returned, and the message is not transmitted.

On success, these calls return the number of characters sent. On error, -1 is returned, and errno is set appropriately.

Buffer size

Look at /proc/sys/net/ipv4/tcp_rmem (for read) and /proc/sys/net/ipv4/tcp_wmem (for write) to see the minimum, default and maximum memory size values (in byte), respectively. There is also /proc/sys/net/core/rmem_default for recv and /proc/sys/net/core/wmem_default for send.

int n;
unsigned int m = sizeof(n);
int fdsocket;
fdsocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); // example
getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);
// now the variable n will have the socket size



#include <sys/types.h>
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

When a socket is created with socket(2), it exists in a name space (address family) but has no address assigned to it. bind() assigns the address specified by addr to the socket referred to by the file descriptor sockfd. Traditionally, this operation is called “assigning a name to a socket”.

It is normally necessary to assign a local address using bind() before a SOCK_STREAM socket may receive connections (see accept(2)).


# Check the connection. traceroute



Ref. Open Shortest Path First (OSPF) is a routing protocol for Internet Protocol (IP) networks. It uses a link state routing algorithm and falls into the group of interior routing protocols, operating within a single autonomous system (AS).


Find IP address

# CentOS:
ifconfig en0 | grep "inet " | awk '{ print $2 }'
# In .bash_profile:
alias wcfip="ifconfig en0 | grep \"inet \" | awk '{ print \$2 }'"

# Get external IP: Reference.
# the ; means "execute commands sequentially.".
# The echo is used to print newline.
curl; echo
# I prefer this one: (if curl fails, don't echo)
curl && echo

Good DNS servers

Why we should always use a public DNS server? Simply put, it is because DNS is not encrypted! Therefore the Man-In-the-Middle can log and conclude your most visited websites and frequently used softwares (since they are going to visit their websites for news and updates).

Recommended 3rd-party DNS servers:


sudo ./noip2

sudo less /usr/local/etc/no-ip2.conf