Programación de red Linux|Programación UDP

 1. Conceptos y características de UDP

UDP: Protocolo de datagramas de usuario

Protocolo de datagramas de usuario UDP: protocolo sin conexión y poco confiable. UDP no requiere conexión, por lo que realiza una transmisión de alta eficiencia.

Situaciones aplicables: 

  1. Después de recibir datos, es difícil dar una respuesta a la red.
  2.  para transmisión/multidifusión 
  3. Videollamada QQ/WeChat/llamada de voz
  4. Streaming de medios, VoIP, IPTV y otros servicios de red

 2. Proceso de programación UDP

Proceso de comunicación --- proceso sin conexión (conectar aceptar) 

UDP no puede determinar si el cliente ha salido:  use paquetes de latidos, use el cliente y envíe contenido al servidor con regularidad.

Proceso UDP: (similar al envío de mensajes de texto)

servidor:

Crear un socket de datagrama (socket(,SOCK_DGRAM,))----->tener un teléfono móvil

Vincular información de red (bind()) -----------> Vincular IP y puerto (enviar mensajes de texto para saber a quién enviarlos)

Recibir información (recvfrom()) ---------- -- >Recibir información y obtener la IP y el puerto del remitente.

Cierre el socket (close())-------------->Recepción completada

cliente:

Crear un socket de datagrama (socket())----------------------->Tener un teléfono móvil

Especifique la información de red del servidor-------------------------------- ------- >Tener el número de la otra parte

Enviar información (sendto()) ---------------------------->Enviar mensajes de texto de acuerdo con la información de la estructura completa

Cierre el socket (close())--------------------->Enviado completado

Aviso:

1. Para TCP, el servidor debe ejecutarse primero antes de que el cliente pueda ejecutarse.

2. Para UDP, no hay orden en el que se ejecutan el servidor y el cliente, debido a que no hay conexión, no importa quién inicia primero, el servidor o el cliente.

3. Un servidor UDP puede conectarse a varios clientes al mismo tiempo. Si desea saber qué cliente está iniciando sesión, puede imprimir la IP y el número de puerto en el código del servidor.

La entrevista puede preguntar sobre lo siguiente: Si está interesado, puede probarlo usted mismo.

4. UDP, cuando el cliente usa enviar, necesita agregar conexión, esta conexión no representa la función de la conexión, pero especifica a quién está a punto de enviar datos el cliente. De esta manera no es necesario usar sendto y solo usar send.

5. En TCP, también puede usar recvfrom y sendto. Cuando lo use, escriba los dos últimos parámetros como NULL y estará bien.

3. Interfaz de funciones 

 (1) socket crea un socket

int socket(dominio int, tipo int, protocolo int);

Archivo de encabezado: #include <sys/types.h>

               #incluir <sys/socket.h>

dominio: familia de protocolos

                AF_UNIX, AF_LOCAL comunicación local

                AF_INET ipv4

                AF_INET6 ipv6

tipo: tipo de enchufe

                SOCK_STREAM: conector de transmisión

                SOCK_DGRAM: socket de datagrama

protocolo: protocolo: complete 0 para que coincida automáticamente con la capa inferior y ayude automáticamente a hacer coincidir el protocolo correspondiente según el tipo predeterminado del sistema

       Iniciar sesión: IPPROTO_TCP, IPPROTO_UDP, IPPROTO_ICMP

       Capa de red: htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)

Éxito: descriptor de archivo de socket

Fallo: -1, establecer código de error

(2)bind une el zócalo

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

Archivo de encabezado: #include<sys/types.h>

            #incluir<sys/socket.h>

            #incluir<netinet/in.h>

            #incluir<netinet/ip.h>

sockfd: descriptor de archivo de socket

addr: estructura de comunicación (siempre que sea una estructura general, debe completar la estructura correspondiente de acuerdo con el método de comunicación seleccionado; el primer parámetro del socket se determina en el momento de la comunicación y debe forzarse)

Estructura general:

estructura sockaddr {

        en_familia_t en_familia;

        char in_data[14];

}

Estructura de comunicación ipv4:

estructura sockaddr_in {

        sa_family_t sin_family; ----Familia de protocolo

         in_port_t sin_port; ----puerto

        estructura in_addr sin_addr; ----estructura ip

};

estructura in_addr {

         uint32_t s_addr; --dirección ip

};

addrlen: tamaño de la estructura

(3) recvfrom recibe datos

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

                                                                       estructura sockaddr *src_addr, socklen_t *addrlen);

sockfd: descriptor de socket

buf: la primera dirección del área del buffer de recepción

len: el tamaño del área del buffer de recepción

banderas: 0 recibir datos y bloquear

           MSG_DONTWAIT: Establecer sin bloqueo

src_addr: puntero a la estructura de información de red del remitente (el caddr de la otra parte)

addrlen: puntero al tamaño de la estructura de información de red del remitente (el caddr de la otra parte)

valor de retorno:

Éxito: número de bytes recibidos, los datos recibidos son 0:0

Fallo: -1

(4) sendto envía datos

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

                                                                           const estructura sockaddr *dest_addr, socklen_t 

sockfd: descriptor de socket

buf: la primera dirección del área del buffer de envío

len: el tamaño del buffer de envío

banderas: 0 enviar mensaje y bloquear

src_addr: puntero a la estructura de información de red del extremo receptor

addrlen: el tamaño de la estructura de información de red del extremo receptor

valor de retorno: 

        Éxito: número de bytes enviados

        Fallo: -1

4. Código completo 

(1) servidor:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>

int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        perror("sockfd err");
        return -1;
    }

    struct sockaddr_in saddr, caddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[1]));
    saddr.sin_addr.s_addr = inet_addr("0.0.0.0");
    int len = sizeof(caddr);

    if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        perror("bind is err");
        exit(0);
    }
    printf("bind ok\n");
    printf("等待接收客户端内容\n");
    while (1)
    {
        int recvbyte = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&caddr, &len);
        if (recvbyte < 0)
        {
            perror("bind is err");
            exit(0);
        }
        else
        {
            printf("ip:%s  port:%d  内容:%s\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port), buf);
        }
    }
    close(sockfd);
    return 0;
}

(2) cliente:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
//ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        perror("sockfd err");
        return -1;
    }

    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[2]));
    saddr.sin_addr.s_addr = inet_addr(argv[1]);
    int len = sizeof(saddr);
    while (1)
    {
        fgets(buf, sizeof(buf), stdin);
        if (buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = '\0';
        sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&saddr, len);
    }
    close(sockfd);
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/m0_73731708/article/details/132912854
Recomendado
Clasificación