RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

TCP/UDP網(wǎng)絡(luò)編程的基礎(chǔ)知識(shí)合集3

jf_78858299 ? 來(lái)源:百問科技 ? 作者:韋東山 ? 2023-05-18 17:31 ? 次閱讀

4.UDP

UDP沒有傳遞保證機(jī)制,如果傳輸中數(shù)據(jù)丟失,協(xié)議不會(huì)有任何的檢測(cè)或提示。

這樣的好處是傳輸?shù)臄?shù)據(jù)是持續(xù)的,此外它是無(wú)連接的傳輸,比如實(shí)時(shí)視頻時(shí),如果采用TCP,中途有一點(diǎn)點(diǎn)數(shù)據(jù)出錯(cuò)都會(huì)卡住,進(jìn)行等待,產(chǎn)生延時(shí)。加入使用UDP,盡管有少量的丟幀,但數(shù)據(jù)是實(shí)時(shí)的。

4.1 UDP流程圖

圖片

4.2 UDP步驟分析

從流程圖可以看出,UDP比TCP的步驟少多了。

  • 服務(wù)器端:

a. 創(chuàng)建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    }

協(xié)議族改成SOCK_DGRAM。

b. 設(shè)置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設(shè)置還是一樣的。

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. 接收數(shù)據(jù)

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

函數(shù)格式

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

函數(shù)功能

從套接字上接收一個(gè)數(shù)據(jù)報(bào)并保存源地址;

sockfd:標(biāo)識(shí)一個(gè)已連接套接字的描述符

buf:接收數(shù)據(jù)緩沖區(qū)

len:接收數(shù)據(jù)緩沖區(qū)長(zhǎng)度

flags:調(diào)用操作方式,由以下零個(gè)或多個(gè)組成

flags 說明 recv send
MSG_DONTROUTE 繞過路由表查找
?
MSG_DONTWAIT 僅本操作非阻塞 ? ?
MSG_OOB 發(fā)送或接收帶外數(shù)據(jù) ? ?
MSG_PEEK 窺看外來(lái)消息 ?
MSG_WAITALL 等待所有數(shù)據(jù) ?

from:(可選)指針,指向裝有源地址的緩沖區(qū)

fromlen:(可選)指針,指向from緩沖區(qū)長(zhǎng)度值

返回值

若成功,返回讀入的字節(jié)數(shù),否則返回0;

e. 關(guān)閉

1    close(sock_fd);
2    exit(0);
  • 客戶機(jī)端:

a. 創(chuàng)建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    }

協(xié)議族改成SOCK_DGRAM。

b. 設(shè)置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. 發(fā)送數(shù)據(jù)

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

函數(shù)格式

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

函數(shù)功能

向一指定目的地發(fā)送數(shù)據(jù);

sockfd:一個(gè)標(biāo)識(shí)套接字的描述字

buf:發(fā)送數(shù)據(jù)緩沖區(qū)

len:發(fā)送數(shù)據(jù)緩沖區(qū)長(zhǎng)度

flags:調(diào)用方式標(biāo)志位

to:(可選)指針,指向目的的套接字的地址

tolen:目的套接字地址的長(zhǎng)度

返回值

若成功,返回發(fā)送的字節(jié)數(shù),如果連接已中止,返回0,如果發(fā)生錯(cuò)誤,返回-1;

d. 關(guān)閉

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

UDP傳輸?shù)目蛻舳松倭薱onnect(),原本該在connect()函數(shù)里傳入服務(wù)器地址相關(guān)信息,現(xiàn)在變成了在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 測(cè)試結(jié)果

和前面TCP測(cè)試方式一樣,先在Ubuntu主機(jī)上交叉編譯服務(wù)器端代碼,再在Ubuntu主機(jī)上編譯客戶端代碼。

在開發(fā)板上運(yùn)行服務(wù)器端代碼,在Ubuntu主機(jī)先啟動(dòng)tmux分屏,再分別運(yùn)行客戶端代碼。

  • 服務(wù)器端

    圖片

  • 客戶機(jī)端

    圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1353

    瀏覽量

    79055
  • UDP
    UDP
    +關(guān)注

    關(guān)注

    0

    文章

    325

    瀏覽量

    33931
  • 網(wǎng)絡(luò)通信
    +關(guān)注

    關(guān)注

    4

    文章

    797

    瀏覽量

    29795
  • 網(wǎng)絡(luò)編程
    +關(guān)注

    關(guān)注

    0

    文章

    71

    瀏覽量

    10074
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    通信必備知識(shí)!TCPUDP協(xié)議介紹及使用

    TCPUDP是兩個(gè)最常用的通訊協(xié)議。TCP是面向連接的協(xié)議,需要在收發(fā)數(shù)據(jù)前與對(duì)方建立可靠的連接,建立連接的過程為3次握手,斷開連接的過程為4次揮手,確保數(shù)據(jù)傳輸?shù)目煽啃浴?/div>
    的頭像 發(fā)表于 03-15 08:19 ?1862次閱讀
    通信必備<b class='flag-5'>知識(shí)</b>!<b class='flag-5'>TCP</b>與<b class='flag-5'>UDP</b>協(xié)議介紹及使用

    第16章 UDP用戶數(shù)據(jù)報(bào)協(xié)議基礎(chǔ)知識(shí)

    ) 16.1 初學(xué)者重要提示 16.2 UDP基礎(chǔ)知識(shí)參考資料 16.3 UDP基礎(chǔ)知識(shí)點(diǎn) 16.4 TCP
    發(fā)表于 11-02 17:27

    第27章 DNS域名系統(tǒng)基礎(chǔ)知識(shí)

    轉(zhuǎn)最新網(wǎng)絡(luò)教程本章節(jié)為大家講解DNS(Domain Name System,域名系統(tǒng)),通過前面章節(jié)對(duì)TCPUDP的學(xué)習(xí),需要大家對(duì)DNS也有個(gè)基礎(chǔ)的認(rèn)識(shí)。(本章的知識(shí)點(diǎn)主要整理自
    發(fā)表于 11-23 15:50

    網(wǎng)絡(luò)協(xié)議基礎(chǔ)知識(shí)推薦

    目錄一、基礎(chǔ)協(xié)議1、網(wǎng)絡(luò)分層模型2、協(xié)議劃分3、重點(diǎn)解析1)TCP/IP和UDP協(xié)議2)HTTP和HTTPS協(xié)議3)WS和WSS協(xié)議4)SS
    發(fā)表于 07-02 06:56

    TCP(IP)協(xié)議與網(wǎng)絡(luò)編程

    網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)--TCP(IP)協(xié)議與網(wǎng)絡(luò)編程
    發(fā)表于 09-01 15:01 ?0次下載

    TCP-IP_Socket網(wǎng)絡(luò)編程

    網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)--TCP-IP_Socket網(wǎng)絡(luò)編程
    發(fā)表于 09-01 15:01 ?0次下載

    TCP協(xié)議基礎(chǔ)知識(shí)

    TCP 是互聯(lián)網(wǎng)核心協(xié)議之一,本文介紹它的基礎(chǔ)知識(shí)
    的頭像 發(fā)表于 10-16 10:29 ?3621次閱讀
    <b class='flag-5'>TCP</b>協(xié)議<b class='flag-5'>基礎(chǔ)知識(shí)</b>

    udptcp的區(qū)別在哪里

    主要介紹udptcp的區(qū)別在哪里,以及TCP協(xié)議和UDP協(xié)議為什么會(huì)共存?通常我們?cè)谡f到網(wǎng)絡(luò)編程
    發(fā)表于 12-08 14:08 ?8582次閱讀

    TCP UDPSocket調(diào)試工具應(yīng)用程序和GPRS DTU數(shù)傳應(yīng)用的基礎(chǔ)知識(shí)合集

    本文檔的主要內(nèi)容詳細(xì)介紹的是TCP UDPSocket調(diào)試工具應(yīng)用程序和GPRS DTU數(shù)傳應(yīng)用的基礎(chǔ)知識(shí)合集
    發(fā)表于 11-14 17:41 ?13次下載
    <b class='flag-5'>TCP</b> UDPSocket調(diào)試工具應(yīng)用程序和GPRS DTU數(shù)傳應(yīng)用的<b class='flag-5'>基礎(chǔ)知識(shí)</b><b class='flag-5'>合集</b>

    tcpudp協(xié)議的異同

    。UDP 校驗(yàn)和則是包含 UDP 首部和數(shù)據(jù)在內(nèi)的校驗(yàn)結(jié)果。 TCP協(xié)議 TCP協(xié)議基于網(wǎng)絡(luò)層的 IP 協(xié)議提供的是有連接、可靠服務(wù),是基于
    的頭像 發(fā)表于 11-12 14:45 ?4068次閱讀
    <b class='flag-5'>tcp</b>和<b class='flag-5'>udp</b>協(xié)議的異同

    基于Socket的UDPTCP編程解析 1

    TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報(bào)協(xié)議是網(wǎng)絡(luò)體系結(jié)TCP/IP模型中傳輸層一層中的兩個(gè)不同的通信協(xié)議。 TCP:傳輸控制協(xié)議,
    的頭像 發(fā)表于 05-18 17:22 ?962次閱讀
    基于Socket的<b class='flag-5'>UDP</b>和<b class='flag-5'>TCP</b><b class='flag-5'>編程</b>解析 1

    基于Socket的UDPTCP編程解析 2

    TCP(傳輸控制協(xié)議)和UDP(用戶數(shù)據(jù)報(bào)協(xié)議是網(wǎng)絡(luò)體系結(jié)TCP/IP模型中傳輸層一層中的兩個(gè)不同的通信協(xié)議。 TCP:傳輸控制協(xié)議,
    的頭像 發(fā)表于 05-18 17:22 ?649次閱讀
    基于Socket的<b class='flag-5'>UDP</b>和<b class='flag-5'>TCP</b><b class='flag-5'>編程</b>解析 2

    TCP/UDP網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)合集1

    本文主要記錄TCP/UDP網(wǎng)絡(luò)編程基礎(chǔ)知識(shí),采用TCP/U
    的頭像 發(fā)表于 05-18 17:31 ?700次閱讀

    TCP/UDP網(wǎng)絡(luò)編程基礎(chǔ)知識(shí)合集2

    本文主要記錄TCP/UDP網(wǎng)絡(luò)編程基礎(chǔ)知識(shí),采用TCP/U
    的頭像 發(fā)表于 05-18 17:31 ?644次閱讀

    TCPUDP的基本區(qū)別

    順序,UDP不保證 UDP應(yīng)用場(chǎng)景: 面向數(shù)據(jù)報(bào)方式 網(wǎng)絡(luò)數(shù)據(jù)大多為短消息 擁有大量Client 對(duì)數(shù)據(jù)安全性無(wú)特殊要求 網(wǎng)絡(luò)負(fù)擔(dān)非常重,但對(duì)響應(yīng)速度要求高
    的頭像 發(fā)表于 11-13 15:27 ?4610次閱讀
    <b class='flag-5'>TCP</b>與<b class='flag-5'>UDP</b>的基本區(qū)別
    RM新时代网站-首页