Echo server for C + + 3-UDP version

This time we implement a UDP version of echo server.

Functions used to transfer data

UDP sockets do not remain connected as TCP sockets do, so target address information is added every time data is transferred.

Functions used to transfer data:

  1. Send data to the target server.
#include <sys/socket.h>

ssize_t sendto(int sock, void *buff, size_t nbytes, int flags, struct sockaddr *to, socklen_t addrlen);

Where to is the address value of the sockaddr structure variable containing the address information of the target server.

  1. Receive data from the server.
#include <sys/socket.h>

ssize_t recvfrom(int sock, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);

Where from is the address value of the sockaddr structure variable containing the address information of the sender

Server code

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

const int BUF_SIZE = 30;

void error_handling(const char *message);

// Receive a parameter, argv[0] is the port number
int main(int argc, char *argv[]) {
    int server_socket;

    char message[BUF_SIZE];
    ssize_t str_len;
    socklen_t client_addr_size;
    int i;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;

    if (argc != 2) {
        printf("Usage: %s <port>\n", argv[0]);
        exit(1);
    }

    server_socket = socket(PF_INET, SOCK_DGRAM, 0); // Create IPv4 TCP socket
    if (server_socket == -1) {
        error_handling("UDP socket create error");
    }

    // Address information initialization
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET; // IPV4 address family
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Use inaddr? Any to assign the IP address of the server
    server_addr.sin_port = htons(atoi(argv[1])); // Port number is set by the first parameter

    // Assign address information
    if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(sockaddr)) == -1) {
        error_handling("bind() error");
    }

    while (1) {
        client_addr_size = sizeof(client_addr);
        // Read data from client
        str_len = recvfrom(server_socket, message, BUF_SIZE, 0, (struct sockaddr*)&client_addr, &client_addr_size);
        // Send data to client
        sendto(server_socket, message, str_len, 0, (struct sockaddr*)&client_addr, client_addr_size);
    }
    printf("echo server\n");

    return 0;
}

Note: there is no break statement in the while loop, so it is an infinite loop, and the close function will not execute.

Client code

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

const int BUF_SIZE = 30;

void error_handling(const char *message);

// Receive two parameters, argv[0] is the IP address and argv[1] is the port number
int main(int argc, char *argv[]) {
    int sock;
    char message[BUF_SIZE];
    ssize_t str_len;
    socklen_t addr_size;

    struct sockaddr_in server_addr, from_addr;

    if (argc != 3) {
        printf("Usage : %s <IP> <port>\n", argv[0]);
        exit(1);
    }

    sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sock == -1) {
        error_handling("socket() error");
    }

    // Address information initialization
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET; // IPV4 address family
    server_addr.sin_addr.s_addr = inet_addr(argv[1]); // Server IP address
    server_addr.sin_port = htons(atoi(argv[2])); // Server port number

    while (1) {
        fputs("Insert message(q or Q to quit): ", stdout);
        fgets(message, BUF_SIZE, stdin);

        // If you enter Q or Q, exit
        if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) {
            break;
        }

        sendto(sock, message, strlen(message), 0, (struct sockaddr*)&server_addr, sizeof(sockaddr)); // Send data to server
        addr_size = sizeof(from_addr);
        str_len = recvfrom(sock, message, BUF_SIZE, 0, (struct sockaddr*)&from_addr, &addr_size); // receive data
        message[str_len] = 0;
        printf("Message from server: %s", message);
    }
    close(sock);

    return 0;
}

UDP address assignment

UDP address assignment should be done before sendto function call:

  1. Call the bind function.
  2. If the sendto function is called to discover that the address information has not been allocated, the corresponding socket will be automatically assigned IP and port when the sendto function is called for the first time.

Project code

github

Reference resources

TCP/IP network programming

Tags: C++ socket github network Programming

Posted on Sun, 01 Dec 2019 18:29:21 -0800 by richei