UDP通信发送和接收 || UDP实现全双工通信

news2024/11/18 6:47:17

recvfrom


    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);
    功能:
        从套接字中接收数据
    参数:
        sockfd:套接字文件描述符
        buf:存放数据空间首地址
        flags:属性 默认为0 
        src_addr:存放IP地址信息的空间首地址
        addrlen:存放接收到IP地址大小空间的首地址
    返回值:
        成功返回实际接收字节数
        失败返回-1 

修改虚拟机到桥接模式

    点击"虚拟机"
    点击"设置"
    点击"网络适配器"
    选择"桥接模式"
    点击"确定"

3.将网卡桥接到无线网卡
    点击"编辑"
    点击"虚拟网络编辑器"
    点击"更改设置"

4.在Ubuntu中重启网络服务
    sudo /etc/init.d/networking restart 

    ifconfig

bind 
    int bind(int sockfd, const struct sockaddr *addr,
                socklen_t addrlen);
    功能:
        在套接字上绑定一个IP地址和端口号
    参数:
        sockfd:套接字文件描述符
        addr:绑定IP地址空间首地址
        addrlen:绑定IP地址的长度
    返回值:
        成功返回0 
        失败返回-1 

UDP需要注意的细节点:

    1.UDP是无连接,发端退出,收端没有任何影响
    2.UDP发送数据上限,最好不要超过1500个字节
    3.UDP是不安全不可靠的,连续且快速的传输数据容易产生数据丢失

UDP包头长度:8个字节
    源端口号(2个字节)
    目的端口号(2个字节)
    长度(2个字节)
    校验和(2个字节)

wireshark

 抓包工具

  操作流程:
    1.sudo wireshark
      打开wireshark抓包工具
    2.选择抓取数据包的网卡
      any
    3.执行通信的代码
    4.停止通信
    5.设定过滤条件
        ip.addr == IP地址 
        udp 
        tcp 
        udp.port == 端口
 

使用UDP实现文件的发送

发送端代码:

/*************************************************************************
	> File Name: recv_file.c
	> Author: yas
	> Mail: rage_yas@hotmail.com
	> Created Time: Wed 06 Mar 2024 02:11:43 PM CST
 ************************************************************************/

#include<stdio.h>
#include "head.h"
int main(void)
{
    int sockfd = 0;
    struct sockaddr_in sendaddr;
    ssize_t nret = 0;
    char filename[1024] = {0};
    int pf = 0;
    char tmpbuff[1024] = {0};
    int nbyte = 0;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
        perror("fail to socket");
        return -1;
    }


    fgets(filename, sizeof(filename), stdin);

    sendaddr.sin_family = AF_INET;
    sendaddr.sin_port = htons(50000);
    sendaddr.sin_addr.s_addr = inet_addr("192.168.1.174");

    nbyte = sendto(sockfd, filename, strlen(filename), 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr));
    if (nbyte == -1)
    {
        perror("fail to sendto");
        return -1;
    }
    
    pf = open(filename, O_RDONLY);
    if (pf == -1)
    {
        perror("fail to open");
        return -1;
    }

    while(1)
    {
        memset (tmpbuff, 0, sizeof(tmpbuff));
        nret = read(pf, tmpbuff, sizeof(tmpbuff));
        if(nret <= 0)
        {
            break;
        }
        nret = sendto(sockfd, tmpbuff, nret, 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr));
    }

    close(pf);
    close(sockfd);

    return 0;
}

接收端代码:



#include<stdio.h>
#include "head.h"
int main(void)
{
    int sockfd = 0;
    ssize_t nsize = 0;
    struct sockaddr_in recvaddr;
    struct sockaddr_in sendaddr;
    ssize_t nret = 0;
    char filename[1024] = {0};
    socklen_t addlen = sizeof(recvaddr);
    int pf = 0;
    char tmpbuff[1024] = {0};
    int retbind = 0;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
        perror("fail to socket");
        return -1;
    }


    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.1.174");

    retbind = bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
    if (retbind == -1)
    {
        perror("fail to bind");
        return -1;
    }

    //printf("!!!!!!!!!!!\n");
    nsize = recvfrom(sockfd, filename, sizeof(filename), 0,(struct sockaddr *)&sendaddr, &addlen);
    if (-1 == nsize)
    {
        perror("fail to recvfrom");
        return -1;
    }
    //printf("!!!!!!!!!!!\n");
    //printf("filename = %s\n", filename);

    pf = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
    if (pf == -1)
    {
        perror("fail to open");
        return -1;
    }

    while(1)
    {
        memset (tmpbuff, 0, sizeof(tmpbuff));
        nret = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0,(struct sockaddr *)&recvaddr, &addlen);
        if (nret <= 0)
        {
            break;
        }
        write(pf, tmpbuff, nret);
    }

    close(pf);
    close(sockfd);

    return 0;
}

使用UDP实现两个主机间的全双工通信

/*************************************************************************
	> File Name: homework.c
	> Author: yas
	> Mail: rage_yas@hotmail.com
	> Created Time: Wed 06 Mar 2024 06:09:58 PM CST
 ************************************************************************/

#include<stdio.h>
#include "head.h"
struct cilent
{
    char name[32];
    char text[1024];
};

struct cilent mycilent;
struct cilent youcilent;

void *pthreadSend(void *arg)
{
    int sockid = 0;
    struct sockaddr_in recvaddr;
    int nret = 0;

    sockid = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockid == -1)
    {
        perror("fail to socket");
        return NULL;
    }
    
    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.1.152");

    scanf("%s", mycilent.name);
    nret = sendto(sockid, mycilent.name, sizeof(mycilent.name), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
    if (nret == -1)
    {
        perror("fail to sendto");
        return NULL;
    }

    while(1)
    {
        memset(mycilent.text, 0, sizeof(mycilent.text));
        scanf("%s", mycilent.text);
        nret = sendto(sockid, mycilent.text, sizeof(mycilent.text), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
        if (nret == -1)
        {
            perror("fail to sendto");
            return NULL;
        }

        if(strcmp(mycilent.text, ".quit") == 0)
        {
            break;
        }
    }

    close(sockid);
}

void *pthreadRecv(void *argv)
{
    int sockid = 0;
    struct sockaddr_in recvaddr;
    struct sockaddr_in getaddr;
    socklen_t addlen = sizeof(getaddr);
    int nret = 0;

    sockid = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockid == -1)
    {
        perror("fail to socket");
        return NULL;
    }
    
    recvaddr.sin_family = AF_INET;
    recvaddr.sin_port = htons(50000);
    recvaddr.sin_addr.s_addr = inet_addr("192.168.1.174");
    
    bind(sockid, (struct sockaddr *)&recvaddr, sizeof(recvaddr));

    nret = recvfrom(sockid, youcilent.name, sizeof(youcilent.name), 0, (struct sockaddr *)&getaddr, &addlen);
    if (nret == -1)
    {
        perror("fail to sendto");
        return NULL;
    }

    while(1)
    {
        memset(youcilent.text, 0, sizeof(youcilent.text));
        nret = recvfrom(sockid, youcilent.text, sizeof(youcilent.text), 0, (struct sockaddr *)&getaddr, &addlen);
        if (nret == -1)
        {
            perror("fail to sendto");
            return NULL;
        }

        printf("%s(%s:%d)>%s\n", youcilent.name, inet_ntoa(getaddr.sin_addr), ntohs(getaddr.sin_port), youcilent.text);
        if(strcmp(youcilent.text, ".quit") == 0)
        {
            break;
        }
    }
    close(sockid);
}

int main(void)
{
    pthread_t Send;
    pthread_t Recv;

    pthread_create(&Send, NULL, pthreadSend, NULL);
    pthread_create(&Recv, NULL, pthreadRecv, NULL);

    pthread_join(Send, NULL);
    pthread_join(Recv, NULL);



    return 0;
}

使用线程实现并行收发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1506144.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

康奈尔开源近10万份审稿意见,未来论文发表或将由AI定夺

大语言模型&#xff08;LLMs&#xff09;的进步为自动化论文评审开辟了新途径&#xff0c;这些模型在学术反馈领域展现出巨大潜力。自动化评审的核心优势在于其能够精准指出论文草稿的不足之处&#xff0c;助力作者优化研究。尽管已有丰富的同行评审数据&#xff0c;但现有自动…

利用websocket +定时器简易的实现一个网络聊天室

其实原理非常简单,就是客户端用户通过websoket来连接websocket服务端。然后服务端,收集每个用户发出的消息, 进而将每条用户的消息通过广播的形式推送到每个连接到服务端的客户端。从而实现用户的实时聊天。 // TODO : 我主要是讲一下实现思路。并未完善其功能。 1.后端 依赖 …

云原生(一)、linux快速上手

Linux是一种开源的Unix-like操作系统内核。它是由Linus Torvalds于1991年首次发布&#xff0c;其后经过全球的自由软件社区的持续开发和改进。Linux内核是操作系统的核心部分&#xff0c;但通常与GNU项目合作&#xff0c;以形成完整的操作系统&#xff0c;被称为Linux发行版&am…

每日OJ题_牛客WY28 跳石板(动态规划)

目录 牛客WY28 跳石板 解析代码 牛客WY28 跳石板 跳石板_牛客题霸_牛客网 解析代码 #include <iostream> #include <vector> #include <climits> #include <cmath> using namespace std;void get_div_num(int n, vector<int>& arr) {for…

基于java+springboot+vue实现的农产品智慧物流系统(文末源码+Lw)23-239

课题意义 现如今&#xff0c;信息种类变得越来越多&#xff0c;信息的容量也变得越来越大&#xff0c;这就是信息时代的标志。近些年&#xff0c;计算机科学发展得也越来越快&#xff0c;而且软件开发技术也越来越成熟&#xff0c;因此&#xff0c;在生活中的各个领域&#x…

WEBUI中的完美像素模式(Pixel Perfect)到底是什么意思

在webui的controlnet中&#xff0c;有个选项&#xff0c;叫做“完美像素模式”&#xff0c;英文为“pixel perfect mode”&#xff0c;有很多朋友在使用的时候不知道这个神奇的选项是否应该勾选上&#xff0c;所以有时候排查问题的时候&#xff0c;会反复的选择和去掉勾选&…

机器学习的基础学习笔记

黑马的学习视频 大家常说的人工智能、机器学习、深度学习其实是包含关系&#xff0c;深度学习是机器学习的一种特殊方法&#xff0c;而机器学习又是人工智能的一个子领域。 其中机器学习是使计算机系统能够通过学习经验和数据来改进性能。机器学习算法能够从数据中发现模式&am…

Igraph入门指南 5

2、graph_from系列&#xff0c;将其他R数据结构转换成图 2-1 邻接矩阵转图&#xff1a;graph_from_adjacency_matrix 可以接受Matrix包创建的稀疏矩阵作为参数 邻接矩阵中行的顺序被保留&#xff0c;并作为图中顶点的顺序。 本函数几个重要的参数&#xff1a; weighted&am…

美团 Java 开发笔试热经

Voiceover&#xff1a; 见者有缘&#xff0c;缘来好运。欢迎大家来到我的博客【CS_GUIDER】&#xff1a;&#xff08;建议收藏至浏览器书签&#xff09; https://wlei224.gitee.io &#xff08;建议访问这个&#xff0c;速度极快&#xff09; https://wl2o2o.github.io &#x…

Kafka 面试题及答案整理,最新面试题

Kafka中的Producer API是如何工作的&#xff1f; Kafka中的Producer API允许应用程序发布一流的数据到一个或多个Kafka主题。它的工作原理包括&#xff1a; 1、创建Producer实例&#xff1a; 通过配置Producer的各种属性&#xff08;如服务器地址、序列化方式等&#xff09;来…

数据结构/C++:AVL树

数据结构/C&#xff1a;AVL树 概念实现插入左单旋右单旋左右双旋右左双旋 总代码展示 概念 AVL树是一种自平衡二叉搜索树&#xff08;BST&#xff09;&#xff0c;被命名为Adelson-Velskii和Landis树&#xff0c;以它们的发明者们的名字命名。AVL树通过在插入和删除操作后进行…

嘉立创画PCB板子入门喔

PCB层叠结构 单层板&#xff0c;双层板&#xff08;就是在单层板的基础上过孔到背面&#xff09;&#xff0c;四层板&#xff0c;六层板&#xff08;四层&#xff0c;六层就是在双层板子基础上通过通孔&#xff0c;盲孔&#xff0c;埋空完成&#xff09;一般以偶数去打板。 为什…

2024年掌握人工智能的顶级课程

[AI 课程推荐] 谷歌、微软、哈佛大学, DeepLearning.AI都发布了免费的人工智能和ChatGPT的课程。 以下是 2024 年掌握人工智能的顶级课程: GOOGLE - 生成式人工智能学习路径微软- 为每个人提供生成式人工智能微软 - 人工智能初学者入门哈佛 - CS50 的 Python 人工智能简介Deep…

MATLAB报错:尝试将 SCRIPT imread 作为函数执行

报错&#xff1a; 在执行matlab脚本的时候出现报错。 >> imread 尝试将 SCRIPT imread 作为函数执行: S:\temp_file\matlab\DigitalImageProcessing\imread.m出错 imread (line 2) I imread(S:\temp_file\matlab\DigitalImageProcessing\blueman.png);分析以及解决方…

Java并发编程总结(一)

一、进程与线程 1、进程与线程 1.1、进程 程序一般认为是静态存储的&#xff0c;而进程则是活动的&#xff0c;真正执行的、动态加载到内存的&#xff0c;被CPU执行的。 程序由指令和数据组成&#xff0c;但这些指令要运行&#xff0c;数据要读写&#xff0c;就必须将指令加…

解决 JavaScript heap out of memory 报错

前台运行项目时候提示内存溢出 解决 先执行&#xff1a; export NODE_OPTIONS"--max-old-space-size4096" 再运行&#xff1b; nom run serve

算法---双指针练习-4(盛水最多的容器)

题目 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;盛水最多的容器 2. 讲解算法原理 算法的主要思路是使用双指针的方法&#xff0c;通过不断调整指针的位置来计算面积&#xff0c;并更新最大面积。具体步骤如下&#xff1a; 初始化左指针x为数组…

Chrome浏览器好用的几个扩展程序

Chrome好用的扩展程序 背景目的介绍JsonHandle例子未完待续。。。。。。 背景 偶然在往上看到Chrome有很多好用的扩展程序&#xff0c;比较好用&#xff0c;因此记录下比较实用的扩展程序。 目的 记录Chrome浏览器好用的插件。 介绍 JsonHandle下载以及无法扩展插件的解决…

C#实现线性查找算法

C#实现线性查找算法 以下是使用 C# 实现线性查找算法的示例代码&#xff1a; using System;class Program {static int LinearSearch(int[] array, int target){for (int i 0; i < array.Length; i){if (array[i] target){return i; // 如果找到目标&#xff0c;返回其索…

《时间贫困》

作者&#xff1a;【英】凯茜霍姆斯 深陷困境&#xff1a;时间贫困且精疲力竭 我们生活在生产力至上的文化中&#xff0c;忙碌已经成了一种身份的象征&#xff0c;也是个人价值的一种体现。然而&#xff0c;基于我个人的经历和研究&#xff0c;我发现这种忙碌的生活状态并不能…