Network
sockets
Quick overview
Sockets types
Raw socket
Stream socket (SOCK_STREAM)
Datagram socket (SOCK_DGRAM)
Data types
struct addrinfo
struct sockaddr
struct sockaddr_in
struct in_addr
struct sockaddr_storage
Helper functions
inet_pton() - convert address from str to int
inet_ntop() - convert address from int to str
Address binding
Local addr.port Remote addr.port Description
*.port *.* All local interfaces
laddr.lport *.* Specific local interface
laddr.lport raddr.rport One client
Server init
getaddrinfo() - convert hostname to ip address
socket() - create a socket
bind() - associate with a port to listen on
listen() - marks the socket referred as a passive socket and setups the number of
pending connections
accept() - block waiting on a new connection
getnameinfo() - get host and port as strings
Client init
getaddrinfo() - convert hostname to ip address
socket() - create a socket
connect() - connect to a remote port (optionally)
Communication over TCP sockets
send() - returns number of sent bytes or -1
recv() - returns number of received bytes or 0 (closed conn on a remote side) or -1
Communication over UDP sockets
sendto() - returns number of sent bytes or -1
recvfrom() - returns number of received bytes or -1
OR, if connect() was called, use:
send() - returns number of sent bytes or -1
recv() - returns number of received bytes or -1
Closing socket
close() - close and free
shutdown() - close not free with option:
SHUT_RD
SHUT_RDWR
SHUT_WR
Get info
getpeername() - remote side address
gethostname() - local hostname
Socket settings
Blocking mode - fcntl(O_NONBLOCK)
Multiplexing server
getaddrinfo() - convert hostname to ip address
socket() - create a socket
bind() - associate with a port to listen on
listen() - marks the socket referred as a passive socket and setups the number of
pending connections
select/poll/epoll/kqueue - blocks waiting on multiple connections events
getnameinfo() - get host and port as strings
Multiplexing using select
select(num, readfds, writefds, exceptfds, timeout)
1. Manipulate bitmaps of max size 1024 bits using macros FD_SET, FD_CLR,
FD_ISSET, FD_ZERO
2. Select returns modifies bitmaps thus applications should refill the interest sets
for every call.
3. Thus both application and kernel have to scan entire bitmaps on each call to
figure out interest sets and the result sets.
4. Moreover kernel iterates over interest set to find out which file descriptor is
ready.
Multiplexing using poll
Cons
App and kernel still have to scan to
figure out interest and result fd
sets
Kernel still have to check which fd
of interest are ready as far as
there is no state saved.
API
poll(struct pollfd *fds, int nfds, int timeout)
Pros
Relies on array of file descriptors
instead of bitmaps. Thus no 1024
limit.
Interest and result sets are
separated, so app does not need
to update it each time
Multiplexing using epoll in Linux
API
int epoll_create(int size) - Create
interest set
int epoll_ctl(int epfd, int op, int fd, struct
epoll_event *event) - Add fd
int epoll_wait(int epfd, struct epoll_event
*events, int maxevents, int timeout) -
Wait
Two modes: level triggered and edge
triggered
Pros
Stateful, no scan on each time is required
Multiple interest sets in one process
Cons
Can not add multiple descriptors at once
Multiplexing using kqueue in FreeBSD
API
int kqueue(void);
int kevent(int kq, const struct kevent
*changelist, int nchanges,
struct kevent *eventlist, int nevents,
const struct timespec *timeout);
Pros
Stateful, no scan on each time is
required
Multiple interest sets in one process
Can add multiple descriptors at once
Can work not only for sockets, but for
files, timers, signals, ...
Broadcast
setsockopt (SO_BROADCAST)
References
Using network sockets
Scalable Event Multiplexing: epoll vs. kqueue
The C10K problem
Re: Linux's implementation of poll() not scalable?
How to use epoll? A complete example in C
My blog
Learning Network Programming

Network sockets

  • 1.
  • 2.
    Sockets types Raw socket Streamsocket (SOCK_STREAM) Datagram socket (SOCK_DGRAM)
  • 3.
    Data types struct addrinfo structsockaddr struct sockaddr_in struct in_addr struct sockaddr_storage
  • 4.
    Helper functions inet_pton() -convert address from str to int inet_ntop() - convert address from int to str
  • 5.
    Address binding Local addr.portRemote addr.port Description *.port *.* All local interfaces laddr.lport *.* Specific local interface laddr.lport raddr.rport One client
  • 6.
    Server init getaddrinfo() -convert hostname to ip address socket() - create a socket bind() - associate with a port to listen on listen() - marks the socket referred as a passive socket and setups the number of pending connections accept() - block waiting on a new connection getnameinfo() - get host and port as strings
  • 7.
    Client init getaddrinfo() -convert hostname to ip address socket() - create a socket connect() - connect to a remote port (optionally)
  • 8.
    Communication over TCPsockets send() - returns number of sent bytes or -1 recv() - returns number of received bytes or 0 (closed conn on a remote side) or -1
  • 9.
    Communication over UDPsockets sendto() - returns number of sent bytes or -1 recvfrom() - returns number of received bytes or -1 OR, if connect() was called, use: send() - returns number of sent bytes or -1 recv() - returns number of received bytes or -1
  • 10.
    Closing socket close() -close and free shutdown() - close not free with option: SHUT_RD SHUT_RDWR SHUT_WR
  • 11.
    Get info getpeername() -remote side address gethostname() - local hostname
  • 12.
    Socket settings Blocking mode- fcntl(O_NONBLOCK)
  • 13.
    Multiplexing server getaddrinfo() -convert hostname to ip address socket() - create a socket bind() - associate with a port to listen on listen() - marks the socket referred as a passive socket and setups the number of pending connections select/poll/epoll/kqueue - blocks waiting on multiple connections events getnameinfo() - get host and port as strings
  • 14.
    Multiplexing using select select(num,readfds, writefds, exceptfds, timeout) 1. Manipulate bitmaps of max size 1024 bits using macros FD_SET, FD_CLR, FD_ISSET, FD_ZERO 2. Select returns modifies bitmaps thus applications should refill the interest sets for every call. 3. Thus both application and kernel have to scan entire bitmaps on each call to figure out interest sets and the result sets. 4. Moreover kernel iterates over interest set to find out which file descriptor is ready.
  • 15.
    Multiplexing using poll Cons Appand kernel still have to scan to figure out interest and result fd sets Kernel still have to check which fd of interest are ready as far as there is no state saved. API poll(struct pollfd *fds, int nfds, int timeout) Pros Relies on array of file descriptors instead of bitmaps. Thus no 1024 limit. Interest and result sets are separated, so app does not need to update it each time
  • 16.
    Multiplexing using epollin Linux API int epoll_create(int size) - Create interest set int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) - Add fd int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) - Wait Two modes: level triggered and edge triggered Pros Stateful, no scan on each time is required Multiple interest sets in one process Cons Can not add multiple descriptors at once
  • 17.
    Multiplexing using kqueuein FreeBSD API int kqueue(void); int kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); Pros Stateful, no scan on each time is required Multiple interest sets in one process Can add multiple descriptors at once Can work not only for sockets, but for files, timers, signals, ...
  • 18.
  • 19.
    References Using network sockets ScalableEvent Multiplexing: epoll vs. kqueue The C10K problem Re: Linux's implementation of poll() not scalable? How to use epoll? A complete example in C
  • 20.