[introduction to C + + server ----- 8.IPC interprocess communication -- socket]

Posted by mydimension on Wed, 02 Mar 2022 12:52:42 +0100

College students are too boring at home during winter vacation. Sort out the knowledge they have learned before and review it by the way. The level is low and the professionalism is poor. It's only for reference. Don't spray it if you don't like it (no one sees it anyway). It's almost unsealed. Wuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwuwu....

1, TCP/IP protocol cluster

(1) Concept

TCP/IP (Transmission Control Protocol/Internet Protocol) refers to a protocol cluster that can realize information transmission between multiple different networks. TCP/IP protocol refers not only to TCP And IP Two agreements, but one by FTP,SMTP,TCP,UDP The protocol cluster composed of, IP and other protocols is called TCP/IP protocol because TCP protocol and IP protocol are the most representative among TCP/IP protocols.

(2) Composition

TCP/IP transmission protocol is strictly a four layer architecture, including application layer, transmission layer, network layer and data link layer.

Application layer protocols: TFTP, HTTP, SNMP, FTP, SMTP, DNS, Telnet, etc

Transport layer protocol: TCP, UDP

Network layer protocols: IP, ICMP, OSPF, EIGRP, IGMP

Data link layer protocols: SLIP, CSLIP, PPP, MTU

2, socket

Socket is an intermediate software abstraction layer for the communication between application layer and TCP/IP protocol family. It is a group of interfaces. The complex TCP/IP protocol family is hidden behind the socket interface. We only need to use the socket interface.

(1) socket overview

In order to simplify the work of developing communication programs, Berkely school has developed a set of API function standards for network communication programs.

The socket standard is extended to window socket and unix socket.

Network programming in linux is realized through socket interface. Socket is not only a special IO, but also a file descriptor. A complete socket has a related description {protocol, local address, local port, remote address, remote port}; Each socket has a unique local socket number, which is assigned by the operating system.

 

(2) socket classification

Streaming socket (SOCK_STREAM)

Streaming socket can provide reliable and connection oriented communication flow. It uses the TCP protocol. TCP ensures the correctness and sequence of data transmission.

Datagram socket (SOCK_DGRAM)

Datagram socket defines a connectionless service. Data is transmitted through independent messages, which is disordered, and does not guarantee reliability and error free. UDP datagram protocol is used.

Raw socket.

The original socket allows direct access to low-level protocols such as IP or ICMP, which is mainly used for the test of new network protocol implementation.

(3) Socket address structure

In the TCP/IP protocol family, the "ip address" of the network layer can uniquely identify the host in the network, while the "protocol + port" of the transport layer can uniquely identify the application (process) in the host. The following two structures contain the necessary information.

struct sockaddr
 {
	unsigned short sa_family; /* address Family, AF_xxx */
	char sa_data[14]; 	  /* 14 bytes Protocol address */
};

sa_family in general, IPV4 uses "AF_INET".

   sa_data contains the address, port and socket number of some remote computers. The data in it is mixed.

struct sockaddr_in {
	short int sin_family; /* Internet Address family */
	unsigned short int sin_port; /* Port number */
	struct in_addr sin_addr; /* Internet address */
	unsigned char sin_zero[8]; /* Add 0 (same size as struct sockaddr)*/
};

These two data types are equivalent and can be converted to each other, usually using sockaddr_in is more convenient

(4) Byte sequence conversion

Because the byte storage order of variables in each machine is different (some systems have the high bit in the front and the bottom bit in the back, while some systems have the bottom bit in the front and the high bit in the back), and the data transmitted by the network must be in a unified order. Therefore, for machines with different internal byte representation order and network byte order, it is necessary to convert the data.

 htons()-"Host to Network Short"

Convert host byte order to network byte order (operate on unsigned short 2bytes)

 htonl()-"Host to Network Long" 

Convert host byte order to network byte order (operate on unsigned long 4 bytes)

 ntohs()-"Network to Host Short"

Convert network byte order to host byte order (operate on unsigned short 2bytes)

 ntohl()-"Network to Host Long "

Convert network byte order to host byte order (operate on unsigned long 4 bytes)

(5) Address format conversion

linux provides the conversion function of converting the address in dot format to long integer number.

inet_addr() can convert a string representing IP address with numbers and dots into an unsigned long integer.

inet_ntoa()

inet_aton()

(6) Basic call

socket() bind()  connect()  

listen() accept() send()

recv()          sendto()

recvfrom() close()     

3, Code example

Server and client

The server can receive the message from the client and feed it back to the client

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <string.h>


using namespace std;


int main()//The server
{

    //Network information structure
    struct sockaddr_in s_addr,c_addr;
    int len = sizeof(struct sockaddr_in);
    socklen_t  client_len= sizeof(struct sockaddr_in);
    //socket identifier
    int socket_fd;

    //accept identifier
    int accept_fd;
    /*
    Parameter 1 protocol family IPv4 IPv6
    Parameter 2 TCP/UDP
    Parameter 3 defaults to 0
    */
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0)
    {
        perror("socket error");
        return 0;
    }
    //Protocol family AF is required_ INET indicates IPv4 address AF_INET6 indicates IPv6 address
    s_addr.sin_family = AF_INET;
    //Set the port number because of the problem of byte order conversion at the size end
    s_addr.sin_port = htons(10086);
    //IP address INADDR_ANY generally refers to this machine
    s_addr.sin_addr.s_addr = INADDR_ANY;


    if (bind(socket_fd, (struct sockaddr*)&s_addr, len) < 0)//binding
    {
        perror("bind error");
        return 0;
    }
    //The second parameter is that the server can receive several clients at the same time
    if (listen(socket_fd, 10) < 0)
    {
        perror("listen error");
        return 0;
    }

    pid_t pid,ppid;
    char buffer[50];
    while (1)
    {
        if ((accept_fd = accept(socket_fd, (struct sockaddr*)&c_addr, &client_len)) == -1)
        {
            perror("accept error");
            exit(1);
        }
        else
        {
            send(accept_fd, "Connect to server!", strlen("Connect to server!"), 0);
        }
        printf("\n%s:%d logon server!\n\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));

        ppid = fork();

        if (ppid == 0)//The subprocess is used to receive information from the client and send feedback
        {
            int rec_size;
            pid = fork();    //Create child process again
            if (pid == 0) //The subprocess of the subprocess is used to receive messages
            {
                while (true)
                {
                    bzero(buffer, sizeof(buffer));
                    if ((rec_size = recv(accept_fd, buffer, sizeof(buffer), 0)) == -1)
                    {
                        perror("Error receiving client information");
                    }
                    else if (rec_size != 0)
                    {
                        buffer[rec_size] = '\0';
                        printf("%s:%d said:%s\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port), buffer);

                        if (send(accept_fd, buffer, rec_size, 0) == -1)//Send the message sent by the client back to the client
                        {
                            perror("send error");
                            break;
                        }
                    }
                }
            }
            else if(pid>0)
            {

            }
        }
        else if (ppid > 0)
        {
            close(accept_fd);
        }


    }

   
    return 0;
}

 

The client can send messages to the server, and the server can receive multiple clients

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <string.h>


using namespace std;

int main()
{
    //Network information structure
    struct sockaddr_in s_addr;
    int len = sizeof(struct sockaddr_in);
    //socket identifier
    int client_fd;

 
    /*
    Parameter 1 protocol family IPv4 IPv6
    Parameter 2 TCP/UDP
    Parameter 3 defaults to 0
    */
    client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd < 0)
    {
        perror("socket error");
        return 0;
    }
    //Protocol family required
    s_addr.sin_family = AF_INET;
    //Set the port number because of the problem of byte order conversion at the size end
    s_addr.sin_port = htons(10086);
    //IP address
    s_addr.sin_addr.s_addr = inet_addr("192.168.52.130");

    if (connect(client_fd,(struct sockaddr*)&s_addr, len) < 0)
    {
        perror("connect error");
        return 0;
    }
    char buffer[50];
    int num = 0;
    while (1)
    {
        bzero(buffer, sizeof(buffer));
        printf("\n start ...\n");
        if ((num = recv(client_fd, buffer, sizeof(buffer), 0)) == -1)
        {
            perror("recv");
            exit(1);
        }
        else if (num > 0)
        {
            int len, bytes_sent;
            buffer[num] = '\0';
            printf("received: %s\n", buffer);
            printf("send out:");
            char msg[50] = { '\0'};
            scanf("%s", msg);
            //Send to server
            if (send(client_fd, msg, sizeof(msg), 0) == -1)
            {
                perror("send error");
            }
        }
        else
        {
            //numbytes=0, indicating that the socket has been disconnected
            printf("socket end!\n");
        }

    }

    close(client_fd);

   
    return 0;
}

results of enforcement

 

Topics: C++ Linux ipc