返回顶部
首页 > 资讯 > 服务器 >使用UDP协议实现—翻译服务器
  • 774
分享到

使用UDP协议实现—翻译服务器

udp网络协议网络 2023-08-31 09:08:52 774人浏览 八月长安
摘要

目录 前言 1.设计思路: 2.词库设计 3.设计客户端 4.设计服务端 5.编译客户端和服务端 6.测试结果 7.总结 前言         上一篇文章中,我们使用UDP协议编码完成了一个简单的服务器,实现数据通信,服务器设计出来后

目录

前言

1.设计思路:

2.词库设计

3.设计客户端

4.设计服务端

5.编译客户端和服务端

6.测试结果

7.总结


前言

        上一篇文章中,我们使用UDP协议编码完成了一个简单的服务器,实现数据通信,服务器设计出来后目的不仅仅只是实现数据通信,而是根据客户端发过来的请求,实现一定的需求,今天我们要介绍的是当客户端给服务端发送英文单词,然后服务端获取客户端的请求,将翻译结果返回给客户端,通过这样的方式,实现了一款英文翻译服务器。下面我们就一起具体来看看是如何编码完成。

1.设计思路:

如图所示

第一步:启动服务器,然后服务器加载词库

第二步:客户端向服务器,发送请求

第三步:服务器处理请求查找单词,将查找结果返回给客户端

第四步:客户端获取查询结果

2.词库设计

说明:在这里只是简单模拟实现一个词库,主要是实现业务逻辑

dict.txt:

aunt:姨母brother:兄弟cousin:堂兄弟couple:夫妇dad:爸爸daughter:女儿family:家father:爸爸grandchild:孙子granddaughger:孙女grandfather:祖父grandma:外婆grandpa:外公granny老奶奶

3.设计客户端

udpClient.hpp

#pragma once#include #include #include #include #include #include #include #include #include #include #include #include namespace Client{    using namespace std;    class udpClient    {    public:        udpClient(const string &serverIp, const uint16_t serverPort)            : _serverIp(serverIp), _serverPort(serverPort), _sockfd(-1) {}        void initClient()        {            _sockfd = Socket(AF_INET, SOCK_DGRAM, 0);            if (_sockfd == -1)            {                cerr << "socket error:" << errno << strerror(errno) << endl;                exit(2);            }        }        void run()        {            struct sockaddr_in server;            memset(&server, 0, sizeof(server));            server.sin_family = AF_INET;            server.sin_addr.s_addr = inet_addr(_serverIp.c_str());            server.sin_port = htons(_serverPort);            while (1)            {                string message;                cout << "请输入你想要翻译的单词:";                getline(cin,message);                //发送请求                sendto(_sockfd, message.c_str(), message.size(), 0, (const struct sockaddr *)&server, sizeof(server));                char buffer[1024];                struct sockaddr_in temp;                socklen_t len = sizeof(temp);                //接受查询翻译结果                size_t n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&temp, &len);                if (n >= 0)                    buffer[n] = 0;                cout << "翻译的结果为: " << buffer << endl;            }        }    private:        string _serverIp;        int _sockfd;        uint16_t _serverPort;    };}

udpClient.cc:启动客户端

#include"udpClient.hpp"#includeusing namespace Client;static void Usage(string proc){    cout << "\nUsage:\n\t" << proc << " server_ip server_port\n\n";}int main(int arGC,char* argv[]){    if(argc != 3)    {        Usage(argv[0]);        exit(1);    }    string serverip = argv[1];    uint16_t serverport = atoi(argv[2]);    unique_ptr uct(new udpClient(serverip,serverport));    uct->initClient();    uct->run();    return 0;}

4.设计服务端

udpServer.hpp

#pragma once#include #include #include #include #include #include #include #include #include #include #include #include namespace Server{    using namespace std;    const static string defaultIP = "0.0.0.0";    enum {USAGE_ERR = 1, SOCKET_ERR, BIND_ERR,OPEN_ERR};    typedef function func_t;    class udpServer    {    public:        udpServer(const func_t& cb,uint16_t port, const string &ip = defaultIP)         :_callback(cb),_port(port),_ip(ip),_sockfd(-1)        {}        void initServer()        {            _sockfd = socket(AF_INET,SOCK_DGRAM,0);            if(_sockfd == -1)            {                cerr<<"socket error:" << errno << strerror(errno) << endl;                exit(SOCKET_ERR);            }            struct sockaddr_in local;            bzero(&local,sizeof(local));            local.sin_family = AF_INET;            local.sin_port = htons(_port);            local.sin_addr.s_addr = htonl(INADDR_ANY);            int n = bind(_sockfd,(struct sockaddr*)&local,sizeof(local));            if(n == -1)            {                cerr<<"bind error:" << errno << strerror(errno) << endl;                exit(BIND_ERR);            }        }        void startServer()        {            char buffer[1024];            for(;;)            {                struct sockaddr_in peer;                socklen_t len = sizeof(peer);                ssize_t s = recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);                if(s)                {                    buffer[s] = { 0 };                    string clientIp = inet_ntoa(peer.sin_addr);                    uint16_t clientPort = ntohs(peer.sin_port);                    string message = buffer;                    cout << clientIp << "[" << clientPort << "]" << message << endl;                    //服务器只负责接受数据,处理方法采用回调的方式交给上层处理                    _callback(_sockfd,clientIp,clientPort,message);                }            }        }        ~udpServer()        {}    private:        uint16_t _port;        string _ip;        int _sockfd;        func_t _callback;    };}

udpServer.cc:启动服务端

#include "udpServer.hpp"#include #include #include using namespace Server;static void Usage(string proc){    cout << "\nUsage:\n\t" << proc << " local_port\n\n";}const string DictTxt = "./dict.txt";unordered_map dict;static bool cutString(string& str,string& s1,string& s2,const string& sep){    auto pos = str.find(sep);    if(pos == string::npos)        return false;    s1 = str.substr(0,pos);    s2 = str.substr(pos + sep.size());    return true;}static void initDict(){    ifstream in(DictTxt,iOS::binary);    if(!in.is_open())    {        cerr << "open fail:" << DictTxt << "error" << endl;        exit(OPEN_ERR);    }    string line;    string key,value;    while(getline(in,line))    {        if(cutString(line,key,value,":"))        {            dict.insert(make_pair(key,value));        }    }    in.close();    cout << "load dict success" << endl;}//翻译:void TranslationWord(int sockfd,string clientIp,uint16_t clientPort,string message){    string response_message;    auto iter = dict.find(message);    if(iter == dict.end())         response_message = "unknown";    else         response_message = iter->second;    struct sockaddr_in client;    bzero(&client, sizeof(client));    client.sin_family = AF_INET;    client.sin_port = htons(clientPort);    client.sin_addr.s_addr = inet_addr(clientIp.c_str());    sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr*)&client, sizeof(client));}int main(int argc, char *argv[]){    if (argc != 2)    {        Usage(argv[0]);        exit(USAGE_ERR);    }    //加载词库    initDict();    uint16_t port = atoi(argv[1]);    unique_ptr usvr(new udpServer(TranslationWord,port));    usvr->initServer();    usvr->startServer();    return 0;}

5.编译客户端和服务端

makefile:

.PHONY:allall:udpServer udpClientudpServer:udpServer.ccg++ -o $@ $^ -std=c++11udpClient:udpClient.ccg++ -o $@ $^ -std=c++11.PHONY:cleanclean:rm -f udpServer udpClient

6.测试结果

如图所示:服务端能够准确处理客户端的请求,将翻译查询结果返回给客户端

7.总结

         以上就是使用UDP协议实现的一款翻译服务器,细心的小伙伴也已经发现了,在上面的代码中服务器的任务只是接受请求,然后将请求的数据回调处理,让上层处理业务逻辑,这样的实现方式实现了服务器与业务逻辑代码之间的解耦,如果以后想实现一款别的需求的服务器,只需要更改上层的业务逻辑就可以了。

来源地址:https://blog.csdn.net/qq_65307907/article/details/132164347

--结束END--

本文标题: 使用UDP协议实现—翻译服务器

本文链接: https://lsjlt.com/news/385055.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作