0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

TCP/UDP网络编程的基础知识合集3

jf_78858299 来源:百问科技 作者:韦东山 2023-05-18 17:31 次阅读

4.UDP

UDP没有传递保证机制,如果传输中数据丢失,协议不会有任何的检测或提示。

这样的好处是传输的数据是持续的,此外它是无连接的传输,比如实时视频时,如果采用TCP,中途有一点点数据出错都会卡住,进行等待,产生延时。加入使用UDP,尽管有少量的丢帧,但数据是实时的。

4.1 UDP流程图

图片

4.2 UDP步骤分析

从流程图可以看出,UDP比TCP的步骤少多了。

  • 服务器端:

a. 创建socket

1    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);//AF_INET:IPV4;SOCK_DGRAM:UDP
2    if (-1 == sock_fd)
3    {
4        fprintf(stderr,"socket error:%s\\n\\a", strerror(errno));
5        exit(1);
6    }

协议族改成SOCK_DGRAM。

b. 设置socket

1    memset(&server_addr, 0, sizeof(struct sockaddr_in));//clear
2    server_addr.sin_family = AF_INET;
3    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY:This machine all IP
4    server_addr.sin_port = htons(PORT_NUMBER);

和前面的TCP设置还是一样的。

c. 绑定socket

1    ret = bind(sock_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr));
2    if(-1 == ret)
3    {
4        fprintf(stderr,"bind error:%s\\n\\a", strerror(errno));
5        close(sock_fd);
6        exit(1);
7    }

绑定的操作也没有变。

d. 接收数据

1    addr_len = sizeof(struct sockaddr);
 2    recv_len = recvfrom(sock_fd, recv_buf, 999, 0, (struct sockaddr *)&server_addr, &addr_len);
 3    if (recv_len <= 0)
 4    {
 5        fprintf(stderr, "recvfrom error:%s\\n\\a", strerror(errno));
 6        close(sock_fd);    
 7        exit(1);
 8    }
 9    else
10    {
11        recv_buf[recv_len] = '\\0';
12        printf("Get msg from client%d: %s\\n", client_num, recv_buf);
13    }

所需要头文件

#include

#include

函数格式

int recvfrom(int sockfd, char FAR *buf, int len, int flags, struct sockaddr FAR *from, int FAR *fromlen);

函数功能

从套接字上接收一个数据报并保存源地址;

sockfd:标识一个已连接套接字的描述符

buf:接收数据缓冲区

len:接收数据缓冲区长度

flags:调用操作方式,由以下零个或多个组成

flags 说明 recv send
MSG_DONTROUTE 绕过路由表查找
MSG_DONTWAIT 仅本操作非阻塞
MSG_OOB 发送或接收带外数据
MSG_PEEK 窥看外来消息
MSG_WAITALL 等待所有数据

from:(可选)指针,指向装有源地址的缓冲区

fromlen:(可选)指针,指向from缓冲区长度值

返回值

若成功,返回读入的字节数,否则返回0;

e. 关闭

1    close(sock_fd);
2    exit(0);
  • 客户机端:

a. 创建socket

1    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);//AF_INET:IPV4;SOCK_DGRAM:UDP
2    if (-1 == sock_fd)
3    {
4        fprintf(stderr,"socket error:%s\\n\\a", strerror(errno));
5        exit(1);
6    }

协议族改成SOCK_DGRAM。

b. 设置socket

1    memset(&server_addr, 0, sizeof(struct sockaddr_in));//clear
 2    server_addr.sin_family = AF_INET;
 3    server_addr.sin_port = htons(PORT_NUMBER);
 4    ret = inet_aton(argv[1], &server_addr.sin_addr);
 5    if(0 == ret)
 6    {
 7        fprintf(stderr,"server_ip error.\\n");
 8        close(sock_fd);
 9        exit(1);
10    }

c. 发送数据

1    addr_len = sizeof(struct sockaddr);
2    send_len = sendto(sock_fd, send_buf, strlen(send_buf), 0, (const struct sockaddr *)&server_addr, addr_len);
3    if (send_len <= 0)
4    {
5        fprintf(stderr,"send error:%s\\n\\a", strerror(errno));
6        close(sock_fd);
7        exit(1);
8    }

所需要头文件

#include

#include

函数格式

int sendto(int sockfd, char FAR *buf, int len, int flags, struct sockaddr FAR *to, int FAR *tolen);

函数功能

向一指定目的地发送数据;

sockfd:一个标识套接字的描述字

buf:发送数据缓冲区

len:发送数据缓冲区长度

flags:调用方式标志位

to:(可选)指针,指向目的的套接字的地址

tolen:目的套接字地址的长度

返回值

若成功,返回发送的字节数,如果连接已中止,返回0,如果发生错误,返回-1;

d. 关闭

1    close(sock_fd);
2    exit(0);

UDP传输的客户端少了connect(),原本该在connect()函数里传入服务器地址相关信息,现在变成了在sendto()里传入。

4.3 UDP完整代码

1/*
 2* udp_server.c
 3# Copyright (C) 2017 hceng, 
 9#include 
10#include 
11#include       
12#include 
13#include 
14#include 
15#include 
16#include 
17#include 
18#include 
19#include 
20
21#define PORT_NUMBER 8888
22
23/* socket->bind->recvfrom/sendto->close */
24
25int main(int argc, char **argv)
26{
27    int sock_fd;
28    struct sockaddr_in server_addr;
29    struct sockaddr_in client_addr;
30    int ret;
31    int addr_len;
32    int recv_len;
33    unsigned char recv_buf[1000];
34
35    /* socket */
36    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);//AF_INET:IPV4;SOCK_DGRAM:UDP
37    if (-1 == sock_fd)
38    {
39        fprintf(stderr,"socket error:%s\\n\\a", strerror(errno));
40        exit(1);
41    }
42
43    /* set sockaddr_in parameter*/
44    memset(&server_addr, 0, sizeof(struct sockaddr_in));//clear
45    server_addr.sin_family = AF_INET;
46    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY:This machine all IP
47    server_addr.sin_port = htons(PORT_NUMBER);
48
49    /* bind */
50    ret = bind(sock_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr));
51    if(-1 == ret)
52    {
53        fprintf(stderr,"bind error:%s\\n\\a", strerror(errno));
54        close(sock_fd);
55        exit(1);
56    }
57
58    while (1)
59    {
60        /* recvfrom */
61        addr_len = sizeof(struct sockaddr);
62        recv_len = recvfrom(sock_fd, recv_buf, 999, 0, (struct sockaddr *)&client_addr, &addr_len);
63        if (recv_len <= 0)
64        {
65            fprintf(stderr, "recvfrom error:%s\\n\\a", strerror(errno));
66            close(sock_fd);    
67            exit(1);
68        }
69        else
70        {
71            recv_buf[recv_len] = '\\0';
72            printf("Get msg from client:%s: %s\\n", inet_ntoa(client_addr.sin_addr), recv_buf);
73        }
74    }            
75
76    /* close */
77    close(sock_fd);
78    exit(0); 
79}
1/*
 2* udp_client.c
 3# Copyright (C) 2017 hceng, 
 9#include 
10#include 
11#include 
12#include 
13#include 
14#include 
15#include 
16#include 
17#include 
18#include 
19
20#define PORT_NUMBER 8888
21
22/* socket->bind->recvfrom/sendto->close */
23int main(int argc, char *argv[])
24{
25    int sock_fd;
26    struct sockaddr_in server_addr;
27    int ret;
28    unsigned char send_buf[1000];
29    int send_len;
30    int addr_len;
31
32    if(argc != 2)
33    {
34        fprintf(stderr, "Usage:%s hostname\\n\\a", argv[0]);
35        exit(1);
36    }
37
38    /* socket */
39    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);//AF_INET:IPV4;SOCK_DGRAM:UDP
40    if (-1 == sock_fd)
41    {
42        fprintf(stderr,"socket error:%s\\n\\a", strerror(errno));
43        exit(1);
44    }
45
46    /* set sockaddr_in parameter*/
47    memset(&server_addr, 0, sizeof(struct sockaddr_in));//clear
48    server_addr.sin_family = AF_INET;
49    server_addr.sin_port = htons(PORT_NUMBER);
50    ret = inet_aton(argv[1], &server_addr.sin_addr);
51    if(0 == ret)
52    {
53        fprintf(stderr,"server_ip error.\\n");
54        close(sock_fd);
55        exit(1);
56    }
57
58    while (1)
59    {
60        if (fgets(send_buf, 999, stdin))
61        {
62            /* sendto */
63            addr_len = sizeof(struct sockaddr);
64            send_len = sendto(sock_fd, send_buf, strlen(send_buf), 0, \\
65(const struct sockaddr *)&server_addr, addr_len);
66            if (send_len <= 0)
67            {
68                fprintf(stderr,"send error:%s\\n\\a", strerror(errno));
69                close(sock_fd);
70                exit(1);
71            }
72        }
73    }
74
75    /* close */
76    close(sock_fd);
77    exit(0);
78}

4.4 测试结果

和前面TCP测试方式一样,先在Ubuntu主机上交叉编译服务器端代码,再在Ubuntu主机上编译客户端代码。

在开发板上运行服务器端代码,在Ubuntu主机先启动tmux分屏,再分别运行客户端代码。

  • 服务器端

    图片

  • 客户机端

    图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • TCP
    TCP
    +关注

    关注

    8

    文章

    1349

    浏览量

    78983
  • UDP
    UDP
    +关注

    关注

    0

    文章

    322

    浏览量

    33872
  • 网络通信
    +关注

    关注

    4

    文章

    792

    浏览量

    29758
  • 网络编程
    +关注

    关注

    0

    文章

    71

    浏览量

    10066
收藏 人收藏

    评论

    相关推荐

    通信必备知识TCPUDP协议介绍及使用

    TCPUDP是两个最常用的通讯协议。TCP是面向连接的协议,需要在收发数据前与对方建立可靠的连接,建立连接的过程为3次握手,断开连接的过程为4次挥手,确保数据传输的可靠性。
    的头像 发表于 03-15 08:19 1732次阅读
    通信必备<b class='flag-5'>知识</b>!<b class='flag-5'>TCP</b>与<b class='flag-5'>UDP</b>协议介绍及使用

    第16章 UDP用户数据报协议基础知识

    ) 16.1 初学者重要提示 16.2 UDP基础知识参考资料 16.3 UDP基础知识点 16.4 TCP
    发表于 11-02 17:27

    第27章 DNS域名系统基础知识

    转最新网络教程本章节为大家讲解DNS(Domain Name System,域名系统),通过前面章节对TCPUDP的学习,需要大家对DNS也有个基础的认识。(本章的知识点主要整理自
    发表于 11-23 15:50

    网络协议基础知识推荐

    目录一、基础协议1、网络分层模型2、协议划分3、重点解析1)TCP/IP和UDP协议2)HTTP和HTTPS协议3)WS和WSS协议4)SS
    发表于 07-02 06:56

    TCP(IP)协议与网络编程

    网络编程基础知识--TCP(IP)协议与网络编程
    发表于 09-01 15:01 0次下载

    TCP-IP_Socket网络编程

    网络编程基础知识--TCP-IP_Socket网络编程
    发表于 09-01 15:01 0次下载

    TCP协议基础知识

    TCP 是互联网核心协议之一,本文介绍它的基础知识
    的头像 发表于 10-16 10:29 3593次阅读
    <b class='flag-5'>TCP</b>协议<b class='flag-5'>基础知识</b>

    udptcp的区别在哪里

    主要介绍udptcp的区别在哪里,以及TCP协议和UDP协议为什么会共存?通常我们在说到网络编程
    发表于 12-08 14:08 8557次阅读

    TCP UDPSocket调试工具应用程序和GPRS DTU数传应用的基础知识合集

    本文档的主要内容详细介绍的是TCP UDPSocket调试工具应用程序和GPRS DTU数传应用的基础知识合集
    发表于 11-14 17:41 13次下载
    <b class='flag-5'>TCP</b> UDPSocket调试工具应用程序和GPRS DTU数传应用的<b class='flag-5'>基础知识</b><b class='flag-5'>合集</b>

    tcpudp协议的异同

    UDP 校验和则是包含 UDP 首部和数据在内的校验结果。 TCP协议 TCP协议基于网络层的 IP 协议提供的是有连接、可靠服务,是基于
    的头像 发表于 11-12 14:45 4008次阅读
    <b class='flag-5'>tcp</b>和<b class='flag-5'>udp</b>协议的异同

    基于Socket的UDPTCP编程解析 1

    TCP(传输控制协议)和UDP(用户数据报协议是网络体系结TCP/IP模型中传输层一层中的两个不同的通信协议。 TCP:传输控制协议,
    的头像 发表于 05-18 17:22 936次阅读
    基于Socket的<b class='flag-5'>UDP</b>和<b class='flag-5'>TCP</b><b class='flag-5'>编程</b>解析 1

    基于Socket的UDPTCP编程解析 2

    TCP(传输控制协议)和UDP(用户数据报协议是网络体系结TCP/IP模型中传输层一层中的两个不同的通信协议。 TCP:传输控制协议,
    的头像 发表于 05-18 17:22 633次阅读
    基于Socket的<b class='flag-5'>UDP</b>和<b class='flag-5'>TCP</b><b class='flag-5'>编程</b>解析 2

    TCP/UDP网络编程基础知识合集1

    本文主要记录TCP/UDP网络编程基础知识,采用TCP/U
    的头像 发表于 05-18 17:31 683次阅读

    TCP/UDP网络编程基础知识合集2

    本文主要记录TCP/UDP网络编程基础知识,采用TCP/U
    的头像 发表于 05-18 17:31 623次阅读

    TCPUDP的基本区别

    顺序,UDP不保证 UDP应用场景: 面向数据报方式 网络数据大多为短消息 拥有大量Client 对数据安全性无特殊要求 网络负担非常重,但对响应速度要求高
    的头像 发表于 11-13 15:27 4547次阅读
    <b class='flag-5'>TCP</b>与<b class='flag-5'>UDP</b>的基本区别