Linux network programming basic API
Socket address API
- Byte order
- Large end byte order (network byte order): the high-order byte (2331 bit) of an integer is stored at the low address of the memory, and the low-order byte (07 bit) is stored at the high address of the memory
- Small end byte order (host byte order): the high-order byte of an integer is stored at the high address of the memory, and the low-order byte is stored at the low address of the memory. Now it is commonly used by PC s
- In the socket network programming interface, the structure sockaddr identifies the socket address
#include <bits/socket.h>
struct sockaddr
{
sa_family_t sa_family;
char sa_data[14];
}
- sa_ Family members are variables of the address family type (sa_family_t)
- sa_ The data member is used to store the socket address value, but 14 bytes cannot fully accommodate the address value of most protocol families
#include <bits/socket.h>
struct sockaddr_storage
{
sa_family_t sa_family;
unsigned long int __ss_align;
char __ss_padding[128-sizeof(__ss_align)];
}
- The new socket geological structure provides enough space to store address values, and memory alignment (_ss_align member)
#include <sys/un.h>
struct sockaddr_un
{
sa_family_t sin_family; // Address family AF_UNIX
char sun_path[108]; // File pathname
}
// IPv4
#include <sys/un.h>
struct sockaddr_in
{
sa_family_t sin_family; // Address family AF_INET
u_int16_t sin_port; //Port number, expressed in network byte order
struct in_addr sin_addr; // IPv4 structure
}
struct in_addr
{
u_int32_t s_addr; // IPv4 address, expressed in network byte order
}
// IPv6
#include <sys/un.h>
struct sockaddr_un
{
sa_family_t sin6_family; // Address family AF_INET6
u_int16_t sin6_port; //Port number, expressed in network byte order
u_int43_t sin6_flowinfo; //Stream information, set to 0
struct in6_addr sin6_addr; // IPv4 structure
u_int32_t sin6_scope_id; // scope ID
}
struct in6_addr
{
unsigned char sa_addr[16]; // IPv6 address, expressed in network byte order
}
- All special socket address type variables need to be converted to general socket address type sockaddr in actual use, because the address parameter type used by all socket programming interfaces is sockaddr
Create socket
- UNIX/Linux philosophy: everything is a file
- socket: readable, writable, controllable and closable file descriptor
#include <sys/types.h>
#include <sys/socket.h>
/**
* domain Which underlying protocol family does the high-speed system use (PF_INET/PF_INET6/PF_UNIX)
* type Service type (SOCK_STREAM stream service (TCP), SOCK_UGRAM datagram (UDP), SOCK_NONBLOCK, sock_cloxec)
* protocol A specific protocol selected under the protocol set composed of the first two parameters is set to 0 to use the default protocol
*/
int socket(int domain, int type, int protocol);
Named socket
#include <sys/types.h>
#include <sys/socket.h>
/**
* Will my_ The socket address referred to by addr is assigned to the unnamed sockfd file descriptor, and addrlen is the socket address length
*/
int bind(int sockfd, const struct sockaddr* my_addr, socklen_t addrlen)
Listening socket
- After the socket is named, the system call needs to create a listening queue to store the pending client connections
#include <sys/socket.h>
/**
* sockfd Monitored socket
* backlog Prompt the kernel for the maximum length of the listening queue. If the length of the listening queue exceeds the backlog, the server will not accept new client connections
*/
int listen(int sockfd, int backlog);
Accept connection
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
- accept just takes the connection from the listening queue, regardless of the state of the connection, and doesn't care about any changes in network conditions
Initiate connection
#include <sys/types.h>
#include <sys/socket.h>
// serv_ socket address monitored by addr server
int connect(int sockfd, struct sockaddr *serv_addr, socklen_t *addrlen)
- The server passively accepts the connection through the listen call, and the client actively establishes a connection with the server through connect
Close connection
#include <unistd.h>
// fd socket to be closed
int close(int fd)
- close is to reduce the reference count of fd by 1. The connection will not be closed until the reference count of fd is 0
- In a multi process program, a fork system call will add 1 to the socket reference count opened by the parent process by default. Therefore, the socket must be close d in both the parent process and the child process
#include <unistd.h>
// Direct immediate termination of connection
int shutdown(int sockfd, int howto)