最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux下使用C/C++進(jìn)行UDP網(wǎng)絡(luò)編程詳解

 更新時(shí)間:2024年10月30日 09:48:54   作者:袁本美  
UDP 是User Datagram Protocol 的簡(jiǎn)稱,中文名是用戶數(shù)據(jù)報(bào)協(xié)議,是一種無(wú)連接、不可靠的協(xié)議,本文主要介紹了如何在Linux下使用C/C++進(jìn)行UDP網(wǎng)絡(luò)編程,有需要的可以了解下

UDP 是User Datagram Protocol 的簡(jiǎn)稱,中文名是用戶數(shù)據(jù)報(bào)協(xié)議,是一種無(wú)連接、不可靠的協(xié)議,同樣它也是工作在傳順層。它只是簡(jiǎn)單地實(shí)現(xiàn)從一端主機(jī)到另一端主機(jī)的數(shù)據(jù)傳輸功能,這些數(shù)據(jù)通過(guò) IP 層發(fā)送,在網(wǎng)絡(luò)中傳輸,到達(dá)目標(biāo)主機(jī)的順序是無(wú)法預(yù)知的,因此需要應(yīng)用程序?qū)@些數(shù)據(jù)進(jìn)行排序處理,這就帶來(lái)了很大的不方便,此外,UDP 協(xié)議更沒(méi)有流量控制、擁塞控制等功能,在發(fā)送的一端,UDP 只是把上層應(yīng)用的數(shù)據(jù)封裝到UDP 報(bào)文中,在差錯(cuò)檢測(cè)方面,僅僅是對(duì)數(shù)據(jù)進(jìn)行了簡(jiǎn)單的校驗(yàn),然后將其封裝到 IP 數(shù)據(jù)報(bào)中發(fā)送出去。而在接收端,無(wú)論是否收到數(shù)據(jù),它都不會(huì)產(chǎn)生一個(gè)應(yīng)答發(fā)送給源主機(jī),并且如果接收到數(shù)據(jù)發(fā)送校驗(yàn)錯(cuò)誤,那么接收端就會(huì)丟棄該UDP 報(bào)文,也不會(huì)告訴源主機(jī),這樣子傳輸?shù)臄?shù)據(jù)是無(wú)法保障其準(zhǔn)確性的,如果想要其準(zhǔn)確性,那么就需要應(yīng)用程序來(lái)保障了。

UDP 協(xié)議的特點(diǎn):

  • 無(wú)連接、不可靠;
  • 盡可能提供交付數(shù)據(jù)服務(wù),出現(xiàn)差錯(cuò)直接丟棄,無(wú)反饋;
  • 面向報(bào)文,發(fā)送方的UDP 拿到上層數(shù)據(jù)直接添加個(gè)UDP 首部,然后進(jìn)行校驗(yàn)后就遞交給 IP 層而接收的一方在接收到UDP 報(bào)文后簡(jiǎn)單進(jìn)行校驗(yàn),然后直接去除數(shù)據(jù)遞交給上層應(yīng)用;
  • 速度快,因?yàn)閁DP 協(xié)議沒(méi)有TCP 協(xié)議的握手、確認(rèn)、窗口、重傳、擁塞控制等機(jī)制,UDP 是一個(gè)無(wú)狀態(tài)的傳輸協(xié)議,所以它在傳遞數(shù)據(jù)時(shí)非常快,即使在網(wǎng)絡(luò)擁塞的時(shí)候UDP 也不會(huì)降低發(fā)送的數(shù)據(jù)。 UDP 雖然有很多缺點(diǎn),但也有自己的優(yōu)點(diǎn),所以它也有很多的應(yīng)用場(chǎng)合,因?yàn)樵谌缃竦木W(wǎng)絡(luò)環(huán)境下, UDP 協(xié)議傳輸出現(xiàn)錯(cuò)誤的概率是很小的,并且它的實(shí)時(shí)性是非常好,常用于實(shí)時(shí)視頻的傳輸,比如直播、網(wǎng)絡(luò)電話等,因?yàn)榧词故浅霈F(xiàn)了數(shù)據(jù)丟失的情況,導(dǎo)致視頻卡幀,這也不是什么大不了的事情,所以,UDP協(xié)議還是會(huì)被應(yīng)用與對(duì)傳輸速度有要求,并且可以容忍出現(xiàn)差錯(cuò)的數(shù)據(jù)傳輸中。

在Linux使用socket網(wǎng)絡(luò)編程實(shí)現(xiàn)udp通信流程如下:

1.  初始化socket

int sock_fd = socket(AF_INET , SOCK_DGRAM , 0); 
if(sock_fd < 0){
    perror("failed to open socket");
    return -1;
}

2.  綁定IP和端口號(hào)

/** 綁定IP和端口號(hào) */ 
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; // 本地任意IP
server_addr.sin_port = htons(8888);       // 指定端口號(hào)
int ret = bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(ret < 0)
{
    perror("failed to bind");
    close(sock_fd);
    return -1;
}

3. 設(shè)置組播接收(可選)

std::string multi_addr = "224.0.0.10";
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(multi_addr.c_str());
mreq.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq));
if (0 >ret)
{
    perror("set socket multicast error");
    return false;
}

4. 設(shè)置接收超時(shí)(可選)

/** 設(shè)置接收超時(shí)(可選) */
int mill_sec = 2000;  // 毫秒
struct timeval time_out;
time_out.tv_sec = mill_sec / 1000;
time_out.tv_usec = (mill_sec- time_out.tv_sec * 1000) * 1000;
ret = setsockopt(sock_fd, SOL_SOCKET,SO_RCVTIMEO,&time_out,sizeof (timeval));
if(ret < 0)
{
    perror("udp setTimeOut error!");
}

5.  發(fā)送數(shù)據(jù)

unsigned char buf[1024];
std::string ip = "192.168.1.10";
int port = 1234;
struct sockaddr_in client{};
memset(&client, 0, sizeof(client));
client.sin_addr.s_addr = inet_addr(ip.c_str());
client.sin_family = AF_INET;
client.sin_port = htons(port);
ret = sendto(sock_fd, buf, sizeof(buf), 0, reinterpret_cast<struct sockaddr *>(&client), sizeof(struct sockaddr));
if(ret < 0){
    perror("udpServer send error!");
}else{
    std::cout << "send success!" << std::endl;
}

6. 接收數(shù)據(jù)

unsigned char buffer[1024];
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
while(true)
{
    memset(buffer, 0, sizeof(buffer));
    ssize_t len = recvfrom(sock_fd_, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr *>(&addr), &addr_len);
    if(len > 0)
    {
        std::cout << "received message len : " << len << std::endl;
    }else{
        perror("recv error");
    }
}

7. 完整代碼

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netdb.h>
#include <net/if.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <cstring>
#include <thread>
 
void recv_func(int sock_fd_)
{
unsigned char buffer[1024];
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
while(true)
{
    memset(buffer, 0, sizeof(buffer));
    ssize_t len = recvfrom(sock_fd_, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr *>(&addr), &addr_len);
    if(len > 0)
    {
        std::cout << "received message len : " << len << std::endl;
    }else{
        perror("recv error");
    }
}
}
 
int main(int agrc, char** argv)
{
    int sock_fd = socket(AF_INET , SOCK_DGRAM , 0); 
    if(sock_fd < 0){
        perror("failed to open socket");
        return -1;
    }
 
    /** 綁定IP和端口號(hào) */ 
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY; // 本地任意IP
    server_addr.sin_port = htons(8888);       // 指定端口號(hào)
    int ret = bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if(ret < 0)
    {
        perror("failed to bind");
        close(sock_fd);
        return -1;
    }
 
    /** 設(shè)置組播接收 (可選)*/
std::string multi_addr = "224.0.0.10";
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(multi_addr.c_str());
mreq.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq));
if (0 >ret)
{
    perror("set socket multicast error");
    return false;
}
 
/** 設(shè)置接收超時(shí)(可選) */
int mill_sec = 2000;  // 毫秒
struct timeval time_out;
time_out.tv_sec = mill_sec / 1000;
time_out.tv_usec = (mill_sec- time_out.tv_sec * 1000) * 1000;
ret = setsockopt(sock_fd, SOL_SOCKET,SO_RCVTIMEO,&time_out,sizeof (timeval));
if(ret < 0)
{
    perror("udp setTimeOut error!");
}
 
 
    /** 開(kāi)啟線程接收 */
    std::thread recv_t(recv_func, sock_fd);
    recv_t.detach();
 
    /** 主線程發(fā)送 */
    while (true)
    {
unsigned char buf[1024];
std::string ip = "192.168.1.10";
int port = 1234;
struct sockaddr_in client{};
memset(&client, 0, sizeof(client));
client.sin_addr.s_addr = inet_addr(ip.c_str());
client.sin_family = AF_INET;
client.sin_port = htons(port);
ret = sendto(sock_fd, buf, sizeof(buf), 0, reinterpret_cast<struct sockaddr *>(&client), sizeof(struct sockaddr));
if(ret < 0){
    perror("udpServer send error!");
}else{
    std::cout << "send success!" << std::endl;
}
        
        usleep(50*1000);
    }
}

8. 編譯運(yùn)行

# 編譯
g++ udp_main.cpp -o main -lpthread
# 運(yùn)行
./main

以上就是Linux下使用C/C++進(jìn)行UDP網(wǎng)絡(luò)編程詳解的詳細(xì)內(nèi)容,更多關(guān)于C++ UDP網(wǎng)絡(luò)編程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用C++實(shí)現(xiàn)工資管理中的隨機(jī)教師信息生成功能

    使用C++實(shí)現(xiàn)工資管理中的隨機(jī)教師信息生成功能

    這篇文章主要介紹了使用C++實(shí)現(xiàn)工資管理中的隨機(jī)教師信息生成功能,想要做一個(gè)教師工資管理系統(tǒng),就必須得準(zhǔn)備好數(shù)據(jù),但是這些數(shù)據(jù)如果用手一行一行地敲,那么工作量是非常大的,因此,我就產(chǎn)生了用C語(yǔ)言實(shí)現(xiàn)直接生成大量的教師基本信息的想法,需要的朋友可以參考下
    2023-05-05
  • 解析鴻蒙輕內(nèi)核靜態(tài)內(nèi)存的使用

    解析鴻蒙輕內(nèi)核靜態(tài)內(nèi)存的使用

    摘要:靜態(tài)內(nèi)存實(shí)質(zhì)上是一個(gè)靜態(tài)數(shù)組,靜態(tài)內(nèi)存池內(nèi)的塊大小在初始化時(shí)設(shè)定,初始化后塊大小不可變更。靜態(tài)內(nèi)存池由一個(gè)控制塊和若干相同大小的內(nèi)存塊構(gòu)成??刂茐K位于內(nèi)存池頭部,用于內(nèi)存塊管理。內(nèi)存塊的申請(qǐng)和釋放以塊大小為粒度
    2021-06-06
  • c++ 網(wǎng)絡(luò)庫(kù)asio的優(yōu)勢(shì)

    c++ 網(wǎng)絡(luò)庫(kù)asio的優(yōu)勢(shì)

    這篇文章主要介紹了c++ 網(wǎng)絡(luò)庫(kù)asio的優(yōu)勢(shì),幫助大家更好的利用c++開(kāi)發(fā)服務(wù)端程序,感興趣的朋友可以了解下
    2020-10-10
  • C++?setw()函數(shù)的具體使用

    C++?setw()函數(shù)的具體使用

    本文主要介紹了C++?setw()函數(shù)的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • C 語(yǔ)言中實(shí)現(xiàn)環(huán)形緩沖區(qū)

    C 語(yǔ)言中實(shí)現(xiàn)環(huán)形緩沖區(qū)

    本文主要是介紹 C語(yǔ)言實(shí)現(xiàn)環(huán)形緩沖區(qū),并附有詳細(xì)實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,希望能幫助有需要的小伙伴
    2016-07-07
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表的簡(jiǎn)單實(shí)例

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表的簡(jiǎn)單實(shí)例

    這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表的簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • C語(yǔ)言實(shí)現(xiàn)輸入一個(gè)字符串后打印出該字符串中字符的所有排列

    C語(yǔ)言實(shí)現(xiàn)輸入一個(gè)字符串后打印出該字符串中字符的所有排列

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)輸入一個(gè)字符串后打印出該字符串中字符的所有排列的方法,是數(shù)學(xué)中非常實(shí)用的排列算法,需要的朋友可以參考下
    2014-09-09
  • C++實(shí)現(xiàn)圖像目標(biāo)區(qū)裁剪ImageCropping

    C++實(shí)現(xiàn)圖像目標(biāo)區(qū)裁剪ImageCropping

    本文主要介紹了C++實(shí)現(xiàn)圖像目標(biāo)區(qū)裁剪ImageCropping,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C語(yǔ)言中類型轉(zhuǎn)換不匹配的解決方案

    C語(yǔ)言中類型轉(zhuǎn)換不匹配的解決方案

    本文主要介紹了C語(yǔ)言中類型轉(zhuǎn)換不匹配的解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-12-12
  • C語(yǔ)言求矩陣主對(duì)角線元素及副對(duì)角線元素之和

    C語(yǔ)言求矩陣主對(duì)角線元素及副對(duì)角線元素之和

    這篇文章主要介紹了C語(yǔ)言求矩陣主對(duì)角線元素及副對(duì)角線元素之和實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論

博野县| 潍坊市| 淮北市| 都江堰市| 家居| 铜鼓县| 七台河市| 安庆市| 蓬安县| 建湖县| 平利县| 开平市| 连城县| 芦山县| 康马县| 和龙市| 南和县| 莱州市| 阜南县| 石渠县| 陆丰市| 景德镇市| 宜宾市| 灵璧县| 建德市| 台中市| 天长市| 句容市| 宣威市| 鄂伦春自治旗| 清新县| 黄大仙区| 达尔| 彭泽县| 隆德县| 双柏县| 迁西县| 鲁甸县| 油尖旺区| 兴国县| 济南市|