Socket网络编程之UDP套件字

基于的UDP套件字编程流程

UDP传输层的协议,面向无连接,数据报的传输层协议。
" 无连接 ":不可靠

  • 在网络环境较好的情况下,UDP效率较高
  • 在网络环境较差的情况下,UDP可能存在丢包的情况
  • 同时一些" 实时应用 " 采用UDP
  • 在应用层加一些保证传输可靠的"1

UCP网络应用

  • Recver 接收端(TCP
  • Sender 发送端(TCP

UDP网络应用的编程流程

UDP Sender(接收端)
创建一个套接字

同样使用socket接口申请一个套接字

  • SOCK_DGRAM 类型的套接字

绑定网络地址

同样使用bind接口将一个套接字和一个网络地址进行绑定

数据通信

  • 接收

    复制代码
      RECV(2)                                                                 
        Linux Programmer's Manual                                             
                            RECV(2)
       NAME
             recv, recvfrom, recvmsg - receive a message from a socket
       SYNOPSIS
             #include <sys/types.h>
             #include <sys/socket.h>
             ssize_t recvfrom(int sockfd, void *buf, size_t len, int 
      flags,struct sockaddr *src_addr, socklen_t *addrlen);
             /*
                  @描述:
                      从一个套接字中接收数据
                  @sockfd:
                      接收数据的套接字
                  @buf:
                      接收到的数据所存放的位置/空间
                  @len:
                      接收数据的空间有多大
                  @flags:
                      标志位:
                          一般为0
                  @src_addr:
                      指向网络地址信息的结构体空间,用来存储发送者信息的结构体,可以为
      NULL,表示不关系发送者信息
                  @addrlen:
                      指向网络地址信息结构体的空间大小的指针
                  @return:
                      成功返回实际读取字节数
      				 失败返回-1
             */

关闭套接字

UDP Client(发送端)

创建一个套接字

同样使用socket接口申请一个套接字

  • SOCK_DGRAM 类型的套接字

数据通信

  • 发送
c++ 复制代码
SEND(2)                                                                 
 Linux Programmer's Manual                                               
                  SEND(2)
 NAME
       send, sendto, sendmsg - send a message on a socket
 SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>
       
       ssize_t sendto(int sockfd, const void *buf, size_t len, int 
flags,const struct sockaddr *dest_addr, socklen_t addrlen);
       /*
            @描述:
                通过一个合法套接字往一个指定的地址发送一条消息
            @sockfd:
                网络套接字
            @buf:
                需要发送的内容指针
            @len:
                需要发送的内容长度
            @flags:
                标志位:
                    一般采用0
            @dest_addr:
                目标地址,接收方的网络地址
            @addrlen:
                目标网络地址结构体的大小
            @return:
                成功返回实际发送的字节数
                失败返回-1
       */

关闭套接字

示例

接收端

c++ 复制代码
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <cstring>
#include <arpa/inet.h>
 #include <unistd.h>
using namespace std;
// UDP编程客户端

int main()
{
    // 创建一个套接字
    int socket_udpid = socket(AF_INET, SOCK_DGRAM, 0);
    if(socket_udpid == -1)
    {
        perror("创建套接字失败");
        return -1;
    }
    cout << " 套接字创建成功" << endl;

    // 绑定一个网络地址:(bind)
    struct sockaddr_in addr;// 指定为IPV4
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8989); //指端口
    addr.sin_addr.s_addr = inet_addr("192.168.5.128");
    // sizeof(addr) 返回的值会被隐式转换为 socklen_t 类型。
    if((bind(socket_udpid, (const struct sockaddr* )&addr, sizeof(addr))) == -1)
    {
        perror("绑定失败");
        return -1;
    }
    cout << "绑定成功" << endl;
    // 通信
    while(1)
    {
        // 接收数据
        char buf[1024] = {0};
        struct sockaddr_in  sendInfor;
        socklen_t len = sizeof(sendInfor);
        if(recvfrom(socket_udpid, buf, 1024 , 0 ,(struct sockaddr*) &sendInfor, &len) == -1)
        {
            perror("接收数据失败");
            return -1;
        }
        if(strcmp(buf, "exit") == 0)
    {
        cout << "结束通信" << endl;
        break;
    }
        cout << "接收到的数据是:" << buf << endl;

      
    }
    // 关闭套接字
    close(socket_udpid);
    return 0;
}

发送端

c++ 复制代码
#include <winsock2.h>
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
    // 初始化网络库
    WSADATA wsData;
    WSAStartup(MAKEWORD(2,2) ,&wsData);

    // 创建套接字
    SOCKET socket_udpid = socket(AF_INET, SOCK_DGRAM, 0);
    if(socket_udpid == INVALID_SOCKET)
    {
        cerr <<  "连接失败,错误码:" << WSAGetLastError() << endl;
        WSACleanup();
        return -1;
    }
    // 设置接收端的地址
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(8989);
  addr.sin_addr.s_addr = inet_addr("192.168.5.128");

  int addlen = sizeof(addr);
  
  while(1)
  {
    //发送信息
    char senfbuf[1024] = {0};
    cout << "请输入";
    cin >> senfbuf;
    sendto(socket_udpid, senfbuf, sizeof(senfbuf), 0,(const sockaddr*)&addr, addlen );
    if(strcmp(senfbuf, "exit") == 0)
    {
        cout << "结束通信" << endl;
        break;
    }
  }

//关闭套接字
closesocket(socket_udpid);
return 0;
}
相关推荐
小刘同学3216 分钟前
C++11 特性
c++·c11新特性
真的想上岸啊20 分钟前
学习C++、QT---18(C++ 记事本项目的stylesheet)
开发语言·c++·学习
m0_5522008224 分钟前
《UE5_C++多人TPS完整教程》学习笔记40 ——《P41 装备(武器)姿势(Equipped Pose)》
c++·游戏·ue5
吴free35 分钟前
mac电脑wireshark快速实现http接口抓包
网络·测试工具·http·wireshark
CodeWithMe1 小时前
【Note】《深入理解Linux内核》 Chapter 15 :深入理解 Linux 页缓存
linux·spring·缓存
0wioiw01 小时前
Ubuntu基础(监控重启和查找程序)
linux·服务器·ubuntu
Tipriest_1 小时前
Ubuntu常用的软件格式deb, rpm, dmg, AppImage等打包及使用方法
linux·运维·ubuntu
艾希逐月1 小时前
TCP数据的发送和接收
服务器·网络·tcp/ip
丁劲犇1 小时前
用 Turbo Vision 2 为 Qt 6 控制台应用创建 TUI 字符 MainFrame
开发语言·c++·qt·tui·字符界面·curse
charlie1145141912 小时前
深入理解Qt的SetWindowsFlags函数
开发语言·c++·qt·原理分析