套接字编程2(udp)

Posted 李憨憨_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了套接字编程2(udp)相关的知识,希望对你有一定的参考价值。

服务端

1.创建套接字

    int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sockfd == 0){
        perror("socket error");
        return -1;
    }

2.为套接字绑定地址信息

    //2.为套接字绑定地址信息
    // int bind(套接字描述符, 地址信息, 地址长度)
    struct sockaddr_in addr;//定义IPv4地址结构
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9000);//设置地址端口
    addr.sin_addr.s_addr = inet_addr("192.168.117.135");
    int len = sizeof(addr);
    int ret = bind(sockfd, (struct sockaddr*)&addr, len);
    if(ret < 0){
        perror("bind error");
        return -1;
    }

3.接收数据

        //3.接收数据
        // recvfrom(句柄, 空间, 长度, 标志, 对端地址, 地址长度)
        char buf[1024] = {0};
        struct sockaddr_in paddr;
        int len = sizeof(struct sockaddr_in);
        ret = recvfrom(sockfd, buf, 1023, 0, (struct sockaddr*)&paddr, &len);
        if(ret < 0){
            perror("recvfrom error");
            return -1;
        }
        printf("client say: %s\\n", buf);

4.回复数据

        //4.回复数据
        // int sendto(句柄, 数据, 长度, 标志, 对端地址, 地址长度)
        char *data = "热死了~~";
        ret = sendto(sockfd, data, strlen(data), 0, (struct sockaddr*)&paddr, len);
        if(ret < 0){
            perror("sendto error");
            return -1;
        }

5.关闭套接字

    //5.关闭套接字
    close(sockfd);

客户端

  • 封装实现一个udpsocket类
  • 通过实例化的对象调用对应的成员接口可以实现udp客户端或服务端的搭建
class UdpSocket{
    private:
        int _sockfd;
    public:
        UdpSocket()
            :_sockfd(-1){}
        bool Socket(){
            _sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
            if(_sockfd < 0){
                perror("socket error");
                return false;
            }
            return true;
        }
        bool Bind(string &ip, uint16_t port){
            struct sockaddr_in addr;
            addr.sin_family = AF_INET;
            addr.sin_port = htons(port);
            addr.sin_addr.s_addr = inet_addr(ip.c_str());
            socklen_t len = sizeof(struct sockaddr_in);
            int ret;
            ret = bind(_sockfd, (struct sockaddr*)&addr, len);
            if(ret < 0){
                perror("bind error");
                return false;
            }
            return true;
        }
        bool Send(string &data, string &ip, int port){
            struct sockaddr_in addr;
            addr.sin_family = AF_INET;
            addr.sin_port = htons(port);
            addr.sin_addr.s_addr = inet_addr(ip.c_str());
            socklen_t len = sizeof(struct sockaddr_in);
            int ret = sendto(_sockfd, data.c_str(), data.size(), 0, (struct sockaddr*)&addr, len);
            if(ret < 0){
                perror("sendto error");
                return false;
            }
            return true;
        }
        bool Recv(string *buf, string *ip = NULL, int *port = NULL){
            struct sockaddr_in addr;
            socklen_t len = sizeof(struct sockaddr_in);
            char tmp[4096] = {0};
            int ret = recvfrom(_sockfd, tmp, 4096, 0, (struct sockaddr*)&addr, &len);
            if(ret < 0){
                perror("recvfrom error");
                return false;
            }
            buf->assign(tmp, ret);//自带申请空间拷贝数据
            if(ip != NULL){
                *ip = inet_ntoa(addr.sin_addr);
            }
            if(port != NULL){
                *port = ntohs(addr.sin_port);
            }
            return true;
        }
        bool Close(){
            if(_sockfd != -1){
                close(_sockfd);
            }
            return true;
        }
};

结果演示

此时如果你编译的话就还发现程序报错了!!!
在这里插入图片描述
因为我们这里写的是传入字符串, 但我们实际上传入的"192.168.117.135"属于字符串常量, 不匹配
所以我们只需要给前面加上const修饰就好了.
在这里插入图片描述
这下就没有问题了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为我是在同一个主机上同时打开了一个服务端和两个客户端, 所以两个客户端的IP地址都是一样的, 但是你会发现两个客户端的端口是不一样的.
这是因为我们的客户端没有绑定固定的端口, 所以这里的端口是不同的.
此时我们就要思考了, 如果我们在程序里给客户端绑定一个固定的端口会怎么样?
那么, 我们的第二个客户端将运行不起来, 因为第二个客户端要绑定端口的时候, 这个端口已经被第一个客户端给绑定了, 肯定会绑定失败, 程序退出.
所以我们的客户端不推荐绑定地址端口信息, 有要求的情况下才进行绑定

以上是关于套接字编程2(udp)的主要内容,如果未能解决你的问题,请参考以下文章

Linux:UDP Socket编程(代码实战)

Java网络编程-第三节:UDP数据报套接字(DatagramSocket)编程

Java网络编程-第三节:UDP数据报套接字(DatagramSocket)编程

网络LinuxLinux网络编程-TCP,UDP套接字编程及代码示范

网络LinuxLinux网络编程-TCP,UDP套接字编程及代码示范

linux系统UDP的socket通信编程2