udp 通信程序

接口 或者 udp 通信不清楚可以看前面博客

用c语言写一个服务端udp_srv.c的udp通信;

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>//字节序转换接口头文件
#include <netinet/in.h>//地址结构头,协议类型文件
#include <sys/socket.h>//套接字接口头文件

int main()
{
    //1. 创建套接字
    // int socket(地址域类型, 套接字类型, 协议类型)
    int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sockfd < 0) {
        perror("socket error");
        return -1;
    }
    //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("172.17.0.3");
    int len = sizeof(addr);
    int ret = bind(sockfd, (struct sockaddr*)&addr, len);
    if (ret < 0) {
        perror("bind error");
        return -1;
    }
    while(1){
        //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;
        }
        uint16_t cport = ntohs(paddr.sin_port);
        char *cip = inet_ntoa(paddr.sin_addr);
        printf("client-[%s:%d] say: %s\n", cip, cport, buf);
        //4. 回复数据
        memset(buf, 0x00, 1024);
        printf("server say: ");
        fflush(stdout);
        fgets(buf, 1023, stdin);
        ret = sendto(sockfd, buf, strlen(buf), 0,
                (struct sockaddr*)&paddr, len);
        if (ret < 0 ) {
            perror("sendto error");
            return -1;
        }
    }
    //5. 关闭套接字
    close(sockfd);
    return 0;
}

写一个udp的类udpsocket.hpp,封装接口:

/*
 * 封装实现一个udpsocket类
 * 通过实例化的对象调用对应的成员接口,
 * 可以实现udp客户端或服务端的搭建
 */
#include <cstdio>
#include <iostream>
#include <string>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

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(std::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(std::string &data,const std::string &ip,
                const 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, (sockaddr*)&addr, len);
            if (ret < 0) {
                perror("sendto error");
                return false;
            }
            return true;
        }
        bool Recv(std::string *buf, 
                std::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,
                    (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;
        }
};

调用udpsocketchpp类,写udp客户端udp_cli.cpp

#include "udpsocket.hpp"

#define CHECK_RET(q) if((q)==false){return -1;}
int main()
{
    UdpSocket sock;
    //1. 创建套接字
    CHECK_RET(sock.Socket());
    //2. 绑定地址信息(不推荐)
    while(1) {
        //3. 发送数据
        std::cout << "client say: ";
        std::string buf;
        std::cin >> buf;
        CHECK_RET(sock.Send(buf, "172.17.0.3", 9000));
        //4. 接收数据
        buf.clear();
        CHECK_RET(sock.Recv(&buf));
        std::cout << "server say: " << buf << "\n";
    }
    //5. 关闭套接字
    sock.Close();
    return 0;
}

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值