UDP接口封装

server.h

复制代码
#include <iostream>
#include <string>
#include <vector>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <cstdlib>

using namespace std;

class Server{
public:
    // 修正构造函数名称
    Server(string ip,uint16_t port):sockfd_(-1),ip_(ip),port_(port){}

    bool init(){
        //创建套接字
        int socket_fd = socket(AF_INET,SOCK_DGRAM,0);

        if(socket_fd==-1){
            perror("socket error");
            return false;
        }
        cout<<"socket success"<<endl;

        // 修正成员变量赋值
        sockfd_ = socket_fd;

        //绑定
        struct sockaddr_in local;
        memset(&local, '\0', sizeof(local));
        local.sin_family=AF_INET;
        local.sin_addr.s_addr=inet_addr(ip_.c_str());
        local.sin_port=htons(port_);

        if(bind(sockfd_,(struct sockaddr*)&local,sizeof(struct sockaddr_in))<0){
            perror("bind error");
            return false;
        }
        cout<<"bind success"<<endl;

        return true;

    }

    void start(){
        vector<char>buffer(4096);
        while(1){
            //信息发送方信息
            struct sockaddr_in sendfrom;
            socklen_t len=sizeof(struct sockaddr_in);
            // 修正 recvfrom 函数调用
            ssize_t size = recvfrom(sockfd_,buffer.data(),buffer.size()-1,0,(struct sockaddr*)&sendfrom,&len);
            if(size>0){
                buffer[size]='\0';
                int port = ntohs(sendfrom.sin_port);
                string ip = inet_ntoa(sendfrom.sin_addr);
                cout<<ip<<":"<<port<<"#"<<buffer.data()<<endl;

                //发送响应数据
                string response = "Message received";
                sendto(sockfd_,response.c_str(),response.size(),0,(struct sockaddr*)&sendfrom,len);

            }
            else{
                perror("recvfrom error");
            }
        }
    }

    ~Server(){
        if(sockfd_>=0){
            close(sockfd_);
        }
    }


private:
    //文件描述符
    int sockfd_;
    //ip地址
    string ip_;
    //端口号
    uint16_t port_;

};

server.cpp

复制代码
#include "server.h"

int main(int argc,char*argv[]){
    if(argc<2){
        std::cerr << "Please provide a port number as an argument.";
        return -1;
    }

    //端口号转换
    uint16_t port =atoi(argv[1]);
    std::string ip="127.0.0.1";
    Server server(ip,port);

    server.init();
    server.start();


    return 0;


}

client.h

复制代码
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <cstdlib>

class Client
{
public:
    Client(std::string server_ip, uint16_t server_port)
        :_sockfd(-1)
        , _server_ip(server_ip)
        , _server_port(server_port)
    {}

    bool init()
    {
        // 创建套接字
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sockfd < 0)
        {
            std::cerr << "socket error" << std::endl;
            return false;
        }
        return true;
    }

    void start()
    {
        struct sockaddr_in server;
        memset(&server, '\0', sizeof(server));
        // 协议家族
        server.sin_family = AF_INET;
        // 端口号
        server.sin_port = htons(_server_port);
        // IP
        server.sin_addr.s_addr = inet_addr(_server_ip.c_str());

        std::string input;
        char buffer[1024];
        socklen_t server_len = sizeof(server);

        while (1)
        {
            std::cout << "Please enter# ";
            std::getline(std::cin, input);

            ssize_t sent_bytes = sendto(_sockfd, input.c_str(), input.length(), 0, (struct sockaddr*)&server, server_len);
            if (sent_bytes == -1)
            {
                std::cerr << "sendto error" << std::endl;
                continue;
            }

            // 接收服务器响应
            ssize_t recv_bytes = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&server, &server_len);
            if (recv_bytes > 0)
            {
                buffer[recv_bytes] = '\0';
                std::cout << "Server response: " << buffer << std::endl;
            }
            else if (recv_bytes == -1)
            {
                std::cerr << "recvfrom error" << std::endl;
            }
        }
    }

    ~Client()
    {
        if (_sockfd >= 0)
        {
            close(_sockfd);
        }
    }

private:
    uint16_t _server_port;
    std::string _server_ip;
    int _sockfd;
};    

client.cpp

复制代码
#include"client.h"

int main(int argc, char* argv[])
{
    if (argc < 3)
    {
        std::cout << "name  ip  port" <<std::endl;
        return -1;
    }
    uint16_t port = atoi(argv[2]);
    std::string ip = argv[1];
    Client client(ip, port);

    client.init();
    client.start();

    return 0;
}

编译运行

g++ server.cpp -o server

g++ client.cpp -o client
服务端启动

./server 5555 端口号

./client 127.0.0.1 5555 ip地址 端口号

相关推荐
流浪0014 小时前
计算机网络篇3:端口号与 socket:数据到达主机后,如何找到目标进程?
计算机网络·udp·tcp·端口·网络字节序
91刘仁德1 天前
Linux网络编程从入门到实战:UDP/TCP协议与socket编程全解析
linux·网络·笔记·tcp/ip·udp
91刘仁德1 天前
传输层协议深度拆解:端口寻址、UDP 报文与 TCP 可靠性机制全解析
linux·网络·c++·网络协议·tcp/ip·udp·c
傲世仙尊3 天前
UDP底层与守护进程化-报头结构体skbuff指针移动与自成会话
驱动开发·网络协议·udp
自己的九又四分之三站台3 天前
TCP 与 UDP:从可靠字节流到无连接数据报,怎么选、怎么测
网络协议·tcp/ip·udp
liangshanbo12153 天前
面试题:游戏、直播为什么常用 UDP?KCP 是什么?为什么比 TCP 更适合低延迟场景?
tcp/ip·游戏·udp
阿钱真强道4 天前
27 嵌入式操作系统 | C 网关:串口 ⇄ UDP 转发(先用 UDP 当上位机替身)
c语言·单片机·网关·udp·uloop
别动我齐刘海5 天前
简历技术栈全面复习——UDP / TCP / CAN / ZMQ / Protobuf 通信工程
网络·c++·python·tcp/ip·机器学习·udp·github
星恒讯工业路由器5 天前
车载以太网中的TCP与UDP:诊断、服务通信与网络管理怎么选
网络·tcp/ip·udp
不会就选b5 天前
Linux之再次理解udp
linux·运维·udp