Introduction to network socket programming

The following is a Li's understanding of socket programming, hoping to help you; if there are errors, please point out generously;

1: Socket programming preparation

2: Introduction of socket api

3: The introduction and implementation of client / server of udp protocol

4: The introduction and implementation of the client / server of tcp protocol

1: Socket programming preparation

1:ip address

IP protocol stipulates that all devices on the network must have a unique IP address, for example, the mail must indicate the address of the addressee, so that the postman can deliver the mail. Similarly, each IP packet must contain the IP address of the destination device, so that the packet can be delivered to the destination correctly. The same device cannot have multiple IP addresses. All network devices using IP must have at least one unique IP address. In other words, multiple IP addresses can be assigned to the same network device, but the same IP address cannot be assigned to two or more network devices repeatedly.

At present, the most widely used IP address rule is IPv4, which uses 32-bit binary to specify. As of November 26, 2019, all 4.3 billion IPv4 addresses in the world have been allocated, which means that no more IPv4 addresses can be allocated to ISP s and other large-scale network infrastructure providers. Therefore, most Internet users use dynamic address allocation, even so it is still not enough Although IPV6 appears, IPV6 is still in the early stage of deployment;

2: Port number

The port number is a 2-byte 16 bit integer. The port number is used to identify a process and tell the operating system which process to process the current data. Therefore, the ip address + port number can identify a process (program) on a host;

Note: a port number can only be occupied by one process, and a process can occupy multiple port numbers

3: Communication protocol

Concept: data format agreement used by both sides in network communication
Significance: to realize network interconnection, it is necessary to establish network communication protocol standard and unify network communication data format
Composition: in network communication, each data will include a five tuple (original ip address / source port / destination ip address / destination port / protocol)

4: Protocol layering

In the communication environment, the environment is layered (a kind of encapsulation) according to the services, protocols and interfaces provided, so that the upper layer does not need to care about an implementation of the lower layer and can be used directly; the use is more flexible and convenient;
Advantages: after the protocol is layered, the communication environment is clear, and the specific implementation of each layer's functions will be simplified, making it easier to form standards
Mode: the network communication environment is extremely complex, so in order to realize the network communication function more easily, the whole communication environment is layered

1: IOS seven layer model: application layer presentation layer session layer transport layer network layer link layer physical layer (too many layers, not easy to implement)

2: TCP/IP five layer model: application layer, transport layer, network layer, link layer, physical layer (commonly used)
Application layer: responsible for data communication between applications; self customization protocol; well known protocol (HTTP/FTP/SSH protocol)
Transport layer: responsible for end-to-end data communication (between ports); encapsulate port information (TCP/UDP protocol)
Network layer: responsible for address management and routing; (select the best path); (IP protocol, router)
Link layer: data transmission between adjacent devices (between two network cards, identified by mac address) (Etherne t switch)
Physical layer: responsible for the transmission of photoelectric signal (Ethernet protocol, hub (such as the length and diameter of twisted pair, etc.)

5: Network communication transmission process

Sending information: application layer transmission layer network layer link layer physical layer

Receiving information: physical layer, link layer, network layer, transmission layer, application layer

As shown in the figure below, suppose you want to send a hello with a button;

Note: each layer will record the protocols used by the upper layer

6: Network byte order:

Byte order: the order in which the cpu stores data in memory, and the byte order of the host is big endian byte order and small endian byte order respectively,
Small endian byte order: low address memory low eg: X86 architecture
Large byte order: low address memory high eg: MIPS architecture
In the network communication, we don't know whether the opposite host is big or small, so two hosts with different host bytes will cause data ambiguity when communicating, and the byte order will affect the network communication mainly for the type of storage larger than one byte (int16 ﹐ T, int32 ﹐ T, short, int, long, float, double);
In order to avoid the data ambiguity caused by different host byte order, the unified byte order is defined as network byte order: big endian byte order. Therefore, in writing network communication programs, if the transmission of data larger than one byte type, the conversion of byte order should be considered

Note: the judgment of using large and small end of the consortium can be used

Byte order conversion interface:

Uint32? T htonl (uint32? T hostlong); / / convert 32-bit host byte order to network byte order

        uint16_t htons(uint16_t hostshort);

        uint32_t ntohl(uint32_t netlong);

Uint16? Ntohs (uint16? Netshort); / / converts a 16 bit network byte order to a host byte order

2: Introduction of socket api

1: Client, server

Client: the side that initiates the request actively

Server: the side that passively accepts requests

Note: because the ip address of the client is not fixed, the client can only send the request to the server

2: Network programming process (socket programming process)

Create socket (make connection between network card and process, and create socket structure in kernel)

Binding address information (IP / port / domain) for socket (information stored in socket)

The client sends data to the server, and the client specifies the address of the opposite end. Then the socket will send the data from the bound address

Server receives data: after the data sent by the client reaches the server host, the server operating system decides which socket buffer to put the data into according to the address information of the data (the data is processed by the specified program). The server finds the socket structure in the kernel by creating a socket return descriptor, and then takes the data out of the buffer

Close socket: release resources occupied by socket in kernel

Note: information such as ip, port, domain, receive and send memory buffer are stored in sockt

3: Network programming interface

Create: int socket(int domain, int type, int protocol);
Domain: address domain (AF? INET: ipv4)
Type: socket type sock'u stream / streaming (ordered reliable bidirectional byte stream tcp) sock'u Dgram / datagram (datagram udp)
Protocol: 0-default protocol; ipproto? TCP (6) ipproto? UDP (17)
Return value: file descriptor -- socket file handle
               

Address binding: int bind (int sockfd, struct SOCKADDR * my "'addr, socklen"'t addrlen);
sockfed: socket operation handle, descriptor
My addr: a general address structure, whose type can be determined by my addr - > false

My? Addr.family (IP type)

My? Addr.sin? Port

My "addr. Sin" addr. S "addr (ip address)
addrlen: addr length


Send data: ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
sockfd: socket descriptor
buf: to send to data
len: length of data
flags: usually give 0 (for blocking);
dest_addr: peer address
addrlen: length of opposite address


Receive data: ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
sockfd: socket descriptor
BUF: put the data to be received into buf
len: buf size
flags: default 0 (blocking)
src_addr: peer address
addrlen: address length
Return value: actual received data length
             

Close: int close (int socket);

 

3: The introduction and implementation of client / server of udp protocol

udp features: user datagram protocol -- Connectionless, unreliable, datagram oriented -- applied to video transmission (allowing a small amount of loss, high real-time performance)

Go to the code directly, and analyze the code in detail

1: Client code: udp_cli.cpp

/*========================================================================================================                                                                                   
 Encapsulate and implement a udp socket class; provide an easy-to-use udp interface to implement the udp communication process
 This is the client code
========================================================================================================= */
#include<iostream>
#include<string>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>

class UdpSocket
{
    int m_sockfd;

public:
    UdpSocket():
        m_sockfd(-1)
    {}

    ~UdpSocket()
    {
        Close();
    }

    bool Socket()//Create socket
    {
        m_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//ipv4, streaming, UDP protocol
        if(m_sockfd < 0)
        {
            std::cerr << "socket error\n";
        }
        return true;
    }

    bool Bind(const std::string &ip, uint16_t port)//Bind socket
    {
        struct sockaddr_in addr;//Pair ends
        addr.sin_family = AF_INET;//ipv4 type
        addr.sin_port = htons(port);//Peer port, converted to network byte order
        addr.sin_addr.s_addr = inet_addr(ip.c_str());//ip
        socklen_t len = sizeof(struct sockaddr_in);//ip length
        int ret = bind(m_sockfd, (struct sockaddr*)&addr, len);//binding
        if(ret < 0)
        {
            std::cerr << "bind erroe\n";
            return false;
        }
        return true;
    }

    bool Recv(std::string &buf, std::string &ip, uint16_t &port)//Receiving information
    {
        char tmp[4096];//Buffer
        struct sockaddr_in peeraddr;//Pair ends
        socklen_t len = sizeof(peeraddr);//To endpoint type size
        int ret = recvfrom(m_sockfd, tmp, 4096, 0, (struct sockaddr*)&peeraddr, &len);//Receive, socket descriptor, buffer, buffer hero, block, peer address, peer address size
        if(ret < 0)
        {
            std::cerr << "recvfrom error\n";
            return false;
        }
                
        buf.assign(tmp, ret);//Open a space for buf to specify ret length, and copy tmp (ret returns the length of received information)
        port = ntohs(peeraddr.sin_port);// Convert network byte order to host byte order
        ip = inet_ntoa(peeraddr.sin_addr);/*inet_ntoa,take sockaddr_in.sin_addr Positive number ip Address converted to string type ip Address, but it returns the first address of the buffer,
        return true;
    }

    bool Send(std::string data, std::string ip, uint16_t port)//Send out
    {
        struct sockaddr_in addr;//End address
        addr.sin_family = AF_INET;//IPv4
        addr.sin_port = htons(port);//End port
        addr.sin_addr.s_addr = inet_addr(ip.c_str());//Opposite end ip
        socklen_t len = sizeof(struct sockaddr_in);
        int ret = sendto(m_sockfd, &data[0], data.size(), 0, (struct sockaddr*)&addr, len);//Send: socket operation handle, send to message, send message size, block send, peer endpoint, peer address size
        if(ret < 0)
        {
            std::cerr << "sento error\n";
            return -1;
        }

        return true;
    }

    bool Close()//Close
    {
        if(m_sockfd >= 0)
        {
            close(m_sockfd);
            m_sockfd = -1;
            return true;
        }
        return false;
    }

};

#define CHECK_RET(q) if((q) == false){return -1;}

int main(int argc, char *argv[])//Directly write parameters through main function
{
    if(argc != 3)
    {
        std::cout << "plase scanf ./udp_cli ip port\n";
        return -1;
    }
    UdpSocket sock;//Define a socket programming class

    std::string srv_ip = argv[1];
    uint16_t srv_port = atoi(argv[2]);
    CHECK_RET(sock.Socket());//Create socket

    //The client can assign the appropriate
    //Check "RET (sock. Bind (argv [1], 8000)); / / socket binding

    while(1)
    {
        std::string buf;
        std::cin >> buf;

        CHECK_RET(sock.Send(buf, srv_ip, srv_port));//Send out
        buf.clear();
        CHECK_RET(sock.Recv(buf, srv_ip, srv_port));//Receive
        std::cout << "server say: " <<  buf  << std::endl;
    }

    CHECK_RET(sock.Close());
    return 0;
}


2: Server code udp_srv.c

/*========================================================================================================                                                                                   
 Transport layer based on udp protocol server program    
 1: Create socket    
 2: Binding address information for socket    
 3: receive data    
 4;send data    
 5: Close socket        
========================================================================================================= */    
#include<stdio.h>                                    
#include<unistd.h>                                                   
#include<netinet/in.h>                                                                                                                     
#include<sys/socket.h>    
#include<string.h>    
#include<arpa/inet.h>                    
#include<stdlib.h>            
                          
int main(int argc, char *argv[2])    
{    
    if(argc != 3)                           
    {                 
        printf("Usage: ./main: %s %s\n",argv[1], argv[2]);    
        return -1;                              
    }                        
    int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//Create socket / / ipv4 datagram type udp protocol                                     
    if(sockfd < 0)    
    {                  
        perror("socket error");    
        return -1;                     
    }                         
    struct sockaddr_in addr;//Define ipv6 address structure    
    addr.sin_family = AF_INET;//Address structure type    
    addr.sin_port = htons(atoi(argv[2]));//Binding port    
    addr.sin_addr.s_addr = inet_addr(argv[1]);//Convert string dotted decimal ip address to network byte order, bind ip    
    
    socklen_t len = sizeof(struct sockaddr_in);//Address length    
    int ret = bind(sockfd, (struct sockaddr*)&addr, len);//Address binding operation handle address structure geological structure size    
    if(ret < 0)    
    {    
        perror("bind error"); 
        return -1;
    }

    while(1)
    {
        //receive data
        char buf[1024] = {0};//Buffer
        struct sockaddr_in cliaddr;//Peer address structure
        socklen_t len = sizeof(struct sockaddr_in);//Peer address size
        int ret = recvfrom(sockfd, buf, 1023, 0, (struct sockaddr*)&cliaddr, &len);//Operation handle, buffer, buffer size, block, address, address size
        if(ret < 0)
        {
            perror("recvfrom error");
            close(sockfd);
            return -1;
        }
                                                                                                                                                                                             
        printf("client say: %s\n", buf);
        //output data
        len = sizeof(struct sockaddr_in);
        memset(buf, 0x00, 1024);//Clear buffer
        scanf("%s", buf);
        ret = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr*)&cliaddr, len);//Operation handle, buffer, buffer size, block, peer address

        if(ret < 0)
        {
            perror("sendto error");
            close(sockfd);
            return -1;
        }

    }

    close(sockfd);

    return 0;
}

4: The introduction and implementation of the client / server of tcp protocol

Characteristics of tcp protocol: transmission control protocol -- connection oriented, reliable transmission, providing byte stream transmission service -- applied to file pure file / compressed package / program (high security)

1: Diagram of tcp flow

Note: three times handshake refers to that in the process of establishing a link, the client first sends a syn request to the server, then the server makes an ack reply and syn request to the client, then the client makes an ack request, and only after three times of back and forth can the link be established (because the TCP protocol is connection oriented, it must be determined that both the client and the server are online)

The implementation and analysis of the above functions will be introduced in the code

 

Go to the code directly, and analyze the code in detail

TCP protocol link

A Li directly links to github here. There are four types of links

tcp_cli.cpp Client
tcp_srv Server side
tcpsocket.hpp  tcp package header file
thread_tcp.cpp Multithreaded server
process_tcp.cpp  Multiprocess server

Note: because there are three handshakes in tcp protocol, the server will create a new socket each time when transmitting information, so when multiple clients send requests to the server, the original socket operation handle (fd) will be overwritten, resulting in the previous client link failure, so it needs to be implemented by multiple threads or processes

 

Published 149 original articles, won praise 29, visited 9972
Private letter follow

Tags: socket network Programming iOS

Posted on Fri, 17 Jan 2020 09:21:16 -0500 by thirdeye