UDP接口封装

时间:2025-04-27 08:48:30

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地址  端口号