linux udp编程 绑定失败_udp socket编程

linux udp编程 绑定失败_udp socket编程简介UDP协议与TCP协议一样用于处理数据包,在OSI模型中,两者都位于传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。代码实现#ifndef_SOCKET_HPP_#define_SOCKET_HPP_#include<iostream>#include<sstream>#include<exception>#include<strin

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

简介

UDP协议与TCP协议一样用于处理数据包,在OSI模型中,两者都位于传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

代码实现

#ifndef _SOCKET_HPP_
#define _SOCKET_HPP_

#include <iostream>
#include <sstream>
#include <exception>
#include <string>
#include <stdlib.h>

#include <arpa/inet.h>

#define MAX_BUFFER 1024

using namespace std;

namespace Socket
{ 
   
    typedef int Socket;
    typedef string Ip;
    typedef unsigned int Port;
    typedef string Data;
    
    typedef struct
    { 
   
        Ip ip;
        Port port;
    }Address;
    
    typedef struct
    { 
   
        Address address;
        Data data;
    }Datagram;
    
    struct sockaddr_in* to_sockaddr(Address* a)
    { 
      struct sockaddr_in* ret;

        ret=(struct sockaddr_in*) malloc (sizeof(struct sockaddr_in));
        ret->sin_family = AF_INET;
        inet_aton(a->ip.c_str(),&(ret->sin_addr));
        ret->sin_port=htons(a->port);
            
        return ret;
    }

    Address* from_sockaddr(struct sockaddr_in* address)
    { 
      Address* ret;

        ret=(Address*)malloc(sizeof(Address));
        ret->ip = inet_ntoa(address->sin_addr);
        ret->port = ntohs(address->sin_port);
        
        return ret;
    }

    class Exception
    { 
   
    private:
        string _message;
    public:
        Exception(string error) { 
    this->_message = error; }
        virtual const char* what() { 
    return this->_message.c_str(); }
    };

    class UDP
    { 
   
    private:
        
        Socket _socket_id;
        bool _binded;
        
    public:
        
        UDP(void);
        ~UDP(void);
        void close(void);
        void bind(Port port);
        void send(Ip ip, Port port, Data data);
        Datagram receive();
    };

    UDP::UDP(void)
        { 
   
            this->_socket_id = socket(AF_INET, SOCK_DGRAM, 0);   
            if (this->_socket_id == -1) throw Exception("[Constructor] Cannot create socket");           
            this->_binded = false;
        }

    UDP::~UDP(void)
        { 
   
        }
        
    void UDP::close(void)
        { 
   
            shutdown(this->_socket_id, SHUT_RDWR);
        }
        
    void UDP::bind(Port port)
        { 
   
            struct sockaddr_in address;
            address.sin_family = AF_INET;
            address.sin_addr.s_addr=htonl(INADDR_ANY);
            address.sin_port=htons(port);
            
            if (this->_binded)
            { 
   
                this->close();
                this->_socket_id = socket(AF_INET, SOCK_DGRAM, 0);
            }
            // ::bind() calls the function bind() from <arpa/inet.h> (outside the namespace) 
            if (::bind(this->_socket_id, (struct sockaddr*)&address, sizeof(struct sockaddr_in)) == -1)
            { 
   
                stringstream error;
                error << "[listen_on_port] with [port=" << port << "] Cannot bind socket";
                throw Exception(error.str());
            }
            
            this->_binded = true;
        }
        
    void UDP::send(Ip ip, Port port, Data data)
        { 
   
            struct sockaddr_in address;
            address.sin_family = AF_INET;
            address.sin_port = htons(port);
            inet_aton(ip.c_str(), &address.sin_addr);
            
            if (sendto(this->_socket_id, (void*)data.c_str(), data.length() + 1, 0, (struct sockaddr*)&address, sizeof(struct sockaddr_in)) == -1)
            { 
   
                stringstream error;
                error << "[send] with [ip=" << ip << "] [port=" << port << "] [data=" << data << "] Cannot send";
                throw Exception(error.str());
            }
        }
        
    Datagram UDP::receive()
        { 
   
            int size = sizeof(struct sockaddr_in);
            char *buffer = (char*)malloc(sizeof(char) * MAX_BUFFER);
            struct sockaddr_in address;
            Datagram ret;
            
            if (recvfrom(this->_socket_id, (void*)buffer, MAX_BUFFER, 0, (struct sockaddr*)&address, (socklen_t*)&size) == -1) throw Exception("[receive] Cannot receive");
            
            ret.data = buffer;
            ret.address.ip = inet_ntoa(address.sin_addr);
            ret.address.port = ntohs(address.sin_port);
            
            free(buffer);
            
            return ret;
        }
}

#endif // _SOCKET_HPP_

使用示例

UDP server

#include <iostream>
#include "Socket.hpp"

using namespace std;

int main(void)
{ 
   
    try
    { 
   
        Socket::UDP sock;
        
        sock.bind(2000);
        
        Socket::Datagram received = sock.receive();
        
        cout << received.data << endl;
        
        sock.send("127.0.0.1", 3000, "response");
        
        sock.close();
    }
    catch (Socket::Exception &e)
    { 
   
        cout << e.what() << endl;
    }
    
    return 0;
}

UDP client

#include <iostream>
#include "Socket.hpp"

using namespace std;

int main(void)
{ 
   
    try
    { 
   
        Socket::UDP sock;
        
        sock.bind(3000);
        
        sock.send("127.0.0.1", 2000, "request");
        
        Socket::Datagram received = sock.receive();
        
        cout << received.data << endl;
        
        sock.close();
    }
    catch (Socket::Exception &e)
    { 
   
        cout << e.what() << endl;
    }
    
    return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196172.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java uninstall tool_java卸载工具|java卸载工具(JavaUninstallTool)下载v1.1.0.0 – 欧普软件下载…「建议收藏」

    java uninstall tool_java卸载工具|java卸载工具(JavaUninstallTool)下载v1.1.0.0 – 欧普软件下载…「建议收藏」java卸载工具(JavaUninstallTool)是甲骨文官方发布的一款专门用于卸载JAVA软件的工具,能够非常方便快捷以及彻底的卸载掉JAVA,使用很简单,只需要解压缩即可使用,赶快下载使用吧!软件功能1、检测到的Java版本将向用户显示以供删除2、用户可以选择删除全部版本,也可以选择删除特定的Java版本3、适用于Windows操作系统4、检测并允许删除Java版本1.4…

    2022年5月12日
    33
  • 11. shell循环 for

    11. shell循环 forshell循环for一级目录二级目录三级目录一级目录二级目录三级目录

    2022年7月24日
    5
  • 物联网,大数据和云计算的基本关系和应用场景_云计算物联网大数据的区别

    物联网,大数据和云计算的基本关系和应用场景_云计算物联网大数据的区别  身处信息快速发展的今天,物联网、大数据、云计算这些名词在我们的生活中出现的越来越频繁,看似高大上的三者其实却和我们的生活息息相关。带你来认识下三者之间的关系吧!  大数据  大数据(bigdata),就是指种类多、流量大、容量大、价值高、处理和分析速度快的真实数据汇聚的产物。大数据或称巨量资料或海量数据资源,指的是所涉及的资料量规模巨大到无法透过目前主流软件工具,在合理时间内达到撷取、…

    2022年10月6日
    0
  • HTTP和HTTPS的区别【面试常考】[通俗易懂]

    HTTP和HTTPS的区别【面试常考】[通俗易懂]这个是根据查阅别人的博客,并结合自己的思想总结的,发出来是对自己的检验也希望可以帮到大家;如有错误欢迎指出HTTP和HTTPS是计算机网络中很重要的知识点,面试的时候很容易被问他们的区别,可能每个人都会有自己理解;HTTP是明文传输的,传输过程中容易被拦截、修改或者伪造请求;HTTPS则是在HTTP基础上进行进行了一些信息保护,相比HTTP来说更为安全。这是一个简单的回答,但是比较笼统,如果想要找到好的工作,中间的很多细节还是需要我们去仔细研究的。HTTPS和HTTPHTTP是什..

    2022年10月7日
    0
  • RangeValidator 控件介绍「建议收藏」

    RangeValidator 控件介绍「建议收藏」RangeValidator控件介绍 使用RangeValidator控件可以验证用户输入是否在指定范围之内。将RangeValidator控件的ControlToValidate属性设置为要验证的SelectionList或TextBox的ID。使用MinimumValue和MaximumValue属性指定范围的最小值和最大值。如果验证

    2022年7月12日
    16
  • vue父组件操作子组件的方法_vue父组件获取子组件数据

    vue父组件操作子组件的方法_vue父组件获取子组件数据父组件和子组件我们经常分不清什么是父组件,什么是子组件。现在来简单总结下:我们将某段代码封装成一个组件,而这个组件又在另一个组件中引入,而引入该封装的组件的文件叫做父组件,被引入的组件叫做子组件。具

    2022年7月29日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号