udp套接字编程

1.udp协议:用户数据报---无连接,传输不可靠,面向数据报。

实现不可靠链接,传输不够灵活,但是不存在数据粘包问题。

2.udp客户端与服务端通信流程

 3.代码实现

//udp客户端

#include "udpsocket.hpp"

int main(int argc, char *argv[])
{
    if (argc != 3) {
        std::cout<<"./udp_cli ip port\n";
        return -1;
    }
    std::string srv_ip = argv[1];
    uint16_t srv_port = atoi(argv[2]);

    UdpSocket sock;
    CHECK_RET(sock.Socket());
    while(1) {
        std::string buf;
        std::cout<<"client say:";
        fflush(stdout);
        std::cin >> buf;
        sock.Send(buf, srv_ip, srv_port);

        buf.clear();
        sock.Recv(buf, srv_ip, srv_port);
        std::cout<<"server say:"<<buf<<std::endl;
    }
    sock.Close();
    return 0;
}
//udp服务端

#include "udpsocket.hpp"

int main(int argc, char *argv[])
{
    if (argc != 3) {
        printf("./udp_srv ip port\n");
        return -1;
    }
    std::string srv_ip = argv[1];
    uint16_t srv_port = atoi(argv[2]);

    UdpSocket sock;

    CHECK_RET(sock.Socket());
    CHECK_RET(sock.Bind(srv_ip, srv_port));

    while(1) {
        std::string cli_ip;
        uint16_t cli_port;
        std::string buf;
        sock.Recv(buf, cli_ip, cli_port);
        printf("client[%s:%d]--say:%s\n", cli_ip.c_str(), cli_port,
                buf.c_str());

        buf.clear();
        printf("server say:");
        fflush(stdout);
        std::cin >> buf;
        sock.Send(buf, cli_ip, cli_port);
    }
    sock.Close();
    return 0;
}
//头文件部分

/*=============================================================== 
*   Copyright (C) . All rights reserved.")
*   文件名称: 
*   创 建 者:zhang
*   创建日期:
*   描    述:ind(int sockfd, const struct sockaddr *addr,)ind(int sockfd, const struct sockaddr *addr,)实现封装一个UdpSocket类,向外提供方便的套接字操作接口 
*       bool Socket()       创建套接字
*       bool Bind(std::string &ip, uint16_t port)
*       bool Recv(std::string &buf, std::string &ip, uint16_t port)
*       bool Send(std::string &buf, std::string &ip, uint16_t port)
*       bool Close()
================================================================*/
#include <iostream>
#include <string>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

class UdpSocket
{
    public:
        UdpSocket():_sockfd(-1){
        }
        ~UdpSocket(){
            close(_sockfd);
        }
        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 = bind(_sockfd, (sockaddr*)&addr, len);
            if (ret < 0) {
                perror("bind error");
                return false;
            }
            return true;
        }
        bool Recv(std::string &buf, std::string &ip, uint16_t &port) {
            char tmp[4096] = {0};
            struct sockaddr_in addr;
            socklen_t len = sizeof(struct sockaddr_in);
            int ret = recvfrom(_sockfd, tmp, 4096, 0, (sockaddr*)&addr,
                    &len);
            if (ret < 0) {
                perror("recv error");
                return false;
            }
            buf.assign(tmp, ret);
            ip = inet_ntoa(addr.sin_addr);
            port = ntohs(addr.sin_port);
            return true;
        }
        bool Send(std::string &buf, 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 = sendto(_sockfd, buf.c_str(), buf.size(), 0, 
                    (struct sockaddr*)&addr, len);
            if (ret < 0) {
                perror("sendto error");
                return false;
            }
            return true;
        }
        bool Close() {
            if (_sockfd >= 0){
                close(_sockfd);
                _sockfd = -1;
            }
        }
    private:
        int _sockfd;
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值