问题:如何应用 UDP 进行数据收发?

再论 UDP 协定

  • UDP 是无连贯的(不牢靠的,无应答音讯,数据包无序号标识
  • UDP 是面向数据包的,对应用层数据既不合并也不拆分(保留数据包边界)
  • UDP 没有拥塞管制,网络呈现的拥塞不会使源主机的发送速率升高
  • UDP 反对一对一,一对多,多对一和多对多的交互通信
  • UDP 音讯头开销小,只有 8 个字节(TCP 音讯头共 20 个字节)

UDP 和 IP 的区别

UDP 是建设于 IP 之上的数据传输协定
  • IP 负责将 UDP 数据包从源主机传输到指标主机
  • UDP 则将应用层数据投递到指标 socket (端口号)
UDP 简直残缺 “继承” 了 IP 传输的个性
  • 通信两端无交互,无流控,无超时重发,不具备可靠性

UDP 收发数据

#include "sys/socket.h"ssize_t send(int sock,                // socket 文件描述符             void *buf,               // 须要发送的数据             size_t nbytes,           // 须要发送的数据量             int flags,               // 发送选项             struct sockaddr *to,     // 接管地址信息             socklen_t addrlen);      // to 参数长度ssize_t recvfrom(int sock,            // socket 文件描述符                 void *buf,            // 保留接收数据的地址                 size_t nbytes,        // 可接管的最大数据量                 int flags,            // 接管选项                 struct sockaddr *from, // 接管地址信息                 socklen_t *addrlen);    // 指向保留 from 参数长度的变量地址

UDP 编程模式

编程试验:UDP 数据收发

client.c
#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <stdio.h>#include <unistd.h>#include <string.h>int main(){    int sock = 0;    struct sockaddr_in addr = {0};    struct sockaddr_in remote = {0};    socklen_t len = 0;    char buf[128] = {0};    char input[32] = {0};    int r = 0;    sock = socket(PF_INET, SOCK_DGRAM, 0);    if (sock == -1) {        printf("socket error\n");        return -1;    }    addr.sin_family = AF_INET;    addr.sin_addr.s_addr = htonl(INADDR_ANY);    addr.sin_port = htons(7777);    if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {        printf("udp bind error\n");        return -1;    }    remote.sin_family = AF_INET;    remote.sin_addr.s_addr = inet_addr("127.0.0.1");    remote.sin_port = htons(8888);    while (1) {        printf("Input: ");        scanf("%s", input);        len = sizeof(remote);        sendto(sock, input, strlen(input), 0, (struct sockaddr*)&remote, len);        r = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&remote, &len);        if (r > 0) {            buf[r] = 0;            printf("Recvfrom %s\n", buf);        } else {            break;        }    }    close(sock);    return 0;}
server.c
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <unistd.h>#include <string.h>int main(){    int server = 0;    struct sockaddr_in saddr = {0};    int client = 0;    struct sockaddr_in remote = {0};    socklen_t asize = 0;    int len = 0;    char buf[32] = {0};    int r = 0;    server = socket(PF_INET, SOCK_DGRAM, 0);    if (server == -1) {        printf("server socket error");        return -1;    }    saddr.sin_family = AF_INET;    saddr.sin_addr.s_addr = htonl(INADDR_ANY);    saddr.sin_port = htons(8888);    if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) {        printf("udp server bind error\n");        return -1;    }    printf("udp server start sucess\n");    while (1) {        len = sizeof(remote);        r = recvfrom(server, buf, sizeof(buf), 0, (struct sockaddr*)&remote, &len);        buf[r] = 0;        printf("r = %d\n", r);        printf("buf = %s\n", buf);        printf("remote ip = %s\n", inet_ntoa(remote.sin_addr));        printf("remote port = %d\n", ntohs(remote.sin_port));        sendto(server, buf, r, 0, (struct sockaddr*)&remote, len);    }    close(server);    return 0;}
输入:
server:udp server start sucessr = 5buf = helloremote ip = 127.0.0.1remote port = 7777---client:Input: helloRecvfrom hello

思考:如何进行一对多的 UDP 数据收发?