IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> C++ UDP广播 -> 正文阅读

[网络协议]C++ UDP广播

UDP介绍

UDP是User Datagram Protocol的简称,即用户数据报协议,为一种无连接的传输层协议,提供面向简单不可靠信息传送服务。客户端Client和服务端Server在交互数据之前无需像TCP那样是先建立连接。
在网络质量较差的情况下,UDP协议数据包丢失会比较严重。但由于UDP的特性,其不属于连接型协议,具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,丢失一、两个Packet也不会有太多的影响,同时像微信Wechat聊天。

客户端

#include <arpa/inet.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <netinet/in.h>
#include <string>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <vector>
#include <netdb.h>  
using namespace std;

#define DEST_PORT 5001
#define LOCAL_PORT 8080

int main() {
  int sockfd;

  char ipStr[32];
  char name[256];
  gethostname(name, sizeof(name));

  // 1.创建socket
  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (-1 == sockfd) {
    return false;
    puts("Failed to create socket");
  }

  // 2.设置地址与端口
  struct sockaddr_in addr;
  socklen_t addr_len = sizeof(addr);

  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;         // Use IPV4
  addr.sin_port = htons(LOCAL_PORT); //
  addr.sin_addr.s_addr = htonl(INADDR_ANY); // INADDR_ANY 绑定本地IP

  const int bBroadcast = 1;
  int nb = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
                      (const char *)&bBroadcast, sizeof(bBroadcast));
  if (nb < 0) {
    perror("setsockopt SO_BROADCAST");
    exit(1);
  }

  // 3.绑定获取数据的端口,作为发送方,不绑定也行
  if (bind(sockfd, (struct sockaddr *)&addr, addr_len) == -1) {
    printf("Failed to bind socket on port %d\n", LOCAL_PORT);
    close(sockfd);
    return false;
  }
  char buffer[128];
  memset(buffer, 0, 128);

  int counter = 0;
  while (1) {
    addr.sin_family = AF_INET;
    addr.sin_port = htons(DEST_PORT);
    addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
    
    char send_buf[20] = "Hello!";

    sendto(sockfd, send_buf, strlen(send_buf), 0, (sockaddr *)&addr, addr_len);

    printf("IP sended %s\n", inet_ntoa(addr.sin_addr));
    printf("Sended %d\n", ++counter);
    sleep(1);

    int sz = recvfrom(sockfd, buffer, 128, 0, (sockaddr *)&addr, &addr_len);
    if (sz > 0) {
      buffer[sz] = 0;
      printf("Get Message %d:\n %s\n", counter++, buffer);
      printf("get IP %s \n", inet_ntoa(addr.sin_addr));
      printf("get Port %d \n\n", ntohs(addr.sin_port));
    } else {
      puts("timeout");
    }
  }

  close(sockfd);
  return 0;
}

服务端

#include <arpa/inet.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define DEST_PORT 5001

int main() {

  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (-1 == sockfd) {
    return false;
    puts("Failed to create socket");
  }

  struct sockaddr_in addr;
  socklen_t addr_len = sizeof(addr);

  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;        // Use IPV4
  addr.sin_port = htons(DEST_PORT); //

  const int opt = 1;
  int nb = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt,
                      sizeof(opt));
  if (nb < 0) {
    perror("setsockopt error");
    exit(1);
  }
  // Bind
  // 端口,用来接受之前设定的地址与端口发来的信息,作为接受一方必须bind端口,并且端口号与发送方一致
  if (bind(sockfd, (struct sockaddr *)&addr, addr_len) == -1) {
    printf("Failed to bind socket on port %d\n", DEST_PORT);
    close(sockfd);
    return false;
  }

  char buffer[128];
  memset(buffer, 0, 128);

  int counter = 0;
  while (1) {
    struct sockaddr_in src;
    socklen_t src_len = sizeof(src);
    memset(&src, 0, sizeof(src));

    // 阻塞住接受消息
    int sz = recvfrom(sockfd, buffer, 128, 0, (sockaddr *)&src, &src_len);
    if (sz > 0) {
      buffer[sz] = 0;
      printf("Get Message %d:\n %s\n", counter++, buffer);
      printf("get IP %s \n", inet_ntoa(src.sin_addr));
      printf("get Port %d \n\n", ntohs(src.sin_port));

      struct sockaddr_in sent;
      socklen_t sent_len = sizeof(sent);
      memset(&sent, 0, sizeof(sent));
      sent.sin_family = AF_INET;
      sent.sin_addr = src.sin_addr;
      sent.sin_port = src.sin_port;

      char send_buf[20] = "I am Robot!";

      sendto(sockfd, send_buf, strlen(send_buf), 0, (sockaddr *)&sent,
             sent_len);
    } else {
      puts("timeout");
    }
  }

  close(sockfd);
  return 0;
}

Linux系统上安装g++,然后在上述文件对应的文件夹中打开终端输入:

g++ server.cpp -o server
g++ client.cpp -o client

生成可执行程序后,打开两个终端,各自输入以下:

./server
./client
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:33:55  更:2021-08-09 10:34:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:43:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码