如何創建基于udp的客戶端和服務端

1.先創建好udpServer.hpp、udpServer.cc、udpClient.hpp、udpClient.cc的框架。

#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <functional>
#include"userManager"
#include<pthread.h>
using namespace std;
const static string defaultip = "0.0.0.0";
// typedef function<void(int,string,uint16_t,string)> func_t;
typedef void (*func_t)(int,string,uint16_t,string);
class udpServer
{
public:udpServer(uint16_t port,func_t callback) : _port(port),_callback(callback){}void init(){}void start(){}~udpServer() {}private:int _fd;uint16_t _port;string _ip;func_t _callback;
};
#include "udpServer.hpp"
#include <memory>
#include<fstream>
using namespace std;
int main(int argc, char *argv[])
{if (argc != 2){cout << "輸入錯誤,請重新輸入" << endl;}uint16_t port = atoi(argv[1]);unique_ptr<udpServer> server(new udpServer(port, callback));server->init();server->start();return 0;
}
#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <pthread.h>
using namespace std;
class udpClient
{public:udpClient(string serverip,uint16_t serverport):_serverip(serverip),_serverport(serverport),_fd(-1){}void init(){}void start(){}~udpClient(){}private:int _fd;string _serverip;uint16_t _serverport;pthread_t reader;//這是后期需要的,看不懂接著往下看就可以
};
#include"udpClient.hpp"
#include<memory>
using namespace std;int main(int argc,char* argv[]){if(argc!=3){cout<<"輸入錯誤,請重新輸入"<<endl;}uint16_t port = atoi(argv[2]);string ip = argv[1];unique_ptr<udpClient> client(new udpClient(ip,port));client->init();client->start();
}

2.init初始化。

 //udpServer.hpp
void init(){// 創建套接字返回fd_fd = socket(AF_INET, SOCK_DGRAM, 0);if (_fd == -1){cerr << "socket error:" << errno << ":" << strerror(errno) << endl;exit(1);}// 將fd和ip,port進行綁定struct sockaddr_in sock;sock.sin_family = AF_INET;sock.sin_port = htons(_port);sock.sin_addr.s_addr = INADDR_ANY;int n = bind(_fd, (struct sockaddr *)&sock, sizeof(sock));if (n == -1){cerr << "bind error:" << errno << ":" << strerror(errno) << endl;exit(2);}}
//udpClient.hpp 
void init(){_fd = socket(AF_INET,SOCK_DGRAM,0);if(_fd == -1){cout<<"socket err:"<<errno<<":"<<strerror(errno)<<endl;exit(1);}}

3.start發送、接收數據。

 //udpServer.cc
void callback(int fd, string ip, uint16_t port, string messages)
{sockaddr_in client;socklen_t len = sizeof(client);client.sin_family = AF_INET;client.sin_port = htons(port);client.sin_addr.s_addr = inet_addr(ip.c_str());messages = "服務端的輸出結果:"+messages;sendto(fd, messages.c_str(), messages.size(), 0,(struct sockaddr *)&client, len);}//udpServer.hpp
void start(){char buffer[1024];size_t len = sizeof(buffer);char writer[1024];struct sockaddr_in clientsock;socklen_t clientlen = sizeof(clientsock);while (1)//服務器的本質就是一個死循環{size_t n = recvfrom(_fd, buffer, len-1, 0, (struct sockaddr *)&clientsock, &clientlen);if (n > 0){buffer[n]=0;string ip = inet_ntoa(clientsock.sin_addr); // uint32_t->stringuint16_t port = ntohs(clientsock.sin_port);string messages = buffer;cout << ip << "[" << port << "]" << "#" << messages << endl;_callback(_fd,ip,port,messages);}}}
 //udpCLient.hpp
static void* readroutine(void* args){pthread_detach(pthread_self());udpClient* c = static_cast<udpClient*>(args);sockaddr_in server;socklen_t serverlen = sizeof(server);while(1){char buffer[1024];int len = sizeof(buffer);size_t n = recvfrom(c->_fd, buffer, len-1, 0, (struct sockaddr *)&server, &serverlen);if (n > 0){buffer[n]=0;cout <<buffer << endl;}}}void start(){pthread_create(&reader,NULL,readroutine,(void*)this);char buffer[1024];struct sockaddr_in serveraddr;serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(_serverport);serveraddr.sin_addr.s_addr = inet_addr(_serverip.c_str());while(1){cin>>buffer;ssize_t n = sendto(_fd,buffer,sizeof(buffer),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));if(n == -1){cout<<"sendto err:"<<errno<<":"<<strerror(errno)<<endl;}}}

完整代碼:

udpClient.cc

#include"udpClient.hpp"
#include<memory>
using namespace std;int main(int argc,char* argv[]){if(argc!=3){cout<<"輸入錯誤,請重新輸入"<<endl;}uint16_t port = atoi(argv[2]);string ip = argv[1];unique_ptr<udpClient> client(new udpClient(ip,port));client->init();client->start();
}

?udpClient.hpp

#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <pthread.h>
using namespace std;
class udpClient
{public:udpClient(string serverip,uint16_t serverport):_serverip(serverip),_serverport(serverport),_fd(-1){}void init(){_fd = socket(AF_INET,SOCK_DGRAM,0);if(_fd == -1){cout<<"socket err:"<<errno<<":"<<strerror(errno)<<endl;exit(1);}}static void* readroutine(void* args){pthread_detach(pthread_self());udpClient* c = static_cast<udpClient*>(args);sockaddr_in server;socklen_t serverlen = sizeof(server);while(1){char buffer[1024];int len = sizeof(buffer);size_t n = recvfrom(c->_fd, buffer, len-1, 0, (struct sockaddr *)&server, &serverlen);if (n > 0){buffer[n]=0;cout <<buffer << endl;}}}void start(){pthread_create(&reader,NULL,readroutine,(void*)this);char buffer[1024];struct sockaddr_in serveraddr;serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(_serverport);serveraddr.sin_addr.s_addr = inet_addr(_serverip.c_str());while(1){cin>>buffer;ssize_t n = sendto(_fd,buffer,sizeof(buffer),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));if(n == -1){cout<<"sendto err:"<<errno<<":"<<strerror(errno)<<endl;}}}~udpClient(){}private:int _fd;string _serverip;uint16_t _serverport;pthread_t reader;
};

?udpServer.cc

#include "udpServer.hpp"
#include <memory>
#include<fstream>
using namespace std;
// 處理方式1:翻譯軟件
unordered_map<string, string> dictmap;
void to_map(string messages);
// 1.打開文件,按行讀取
void openfile()
{ifstream in;in.open("dict.txt",std::ios::binary);if(in.is_open()){std::string line;while(getline(in,line)){to_map(line);}}
}
// 2.按行存到map中
void to_map(string messages)
{size_t pos = messages.find(":");dictmap.insert(make_pair(messages.substr(0, pos), messages.substr(pos + 1)));
}
// 3.接收傳來的message并通過map查詢
void translate(int fd, string ip, uint16_t port, string messages)
{sockaddr_in client;socklen_t len = sizeof(client);client.sin_family = AF_INET;client.sin_port = htons(port);client.sin_addr.s_addr = inet_addr(ip.c_str());if (dictmap.find(messages) != dictmap.end()){cout<<"messages:"<<dictmap[messages].c_str()<<endl;sendto(fd, dictmap[messages].c_str(), dictmap[messages].size(), 0,(struct sockaddr *)&client, len);}else{string mes = "無結果";sendto(fd, mes.c_str(), mes.size(),0, (struct sockaddr *)&client, len);}
}
// 4.test測試文件有沒有加載成功
void printdict()
{for (auto e : dictmap){cout << e.first << ":" << e.second << endl;}
}
// 處理方式2:群聊
onlineUser onlineuser;
void group_chat(int fd, string ip, uint16_t port, string messages)
{// 將客戶端的信息傳進來onlineuser.addOnlineUser(ip, port);onlineuser.broadcastMessage(fd, ip, port, messages);
}
// 處理方式3:最簡單版本收到什么原樣返回
void callback(int fd, string ip, uint16_t port, string messages)
{sockaddr_in client;socklen_t len = sizeof(client);client.sin_family = AF_INET;client.sin_port = htons(port);client.sin_addr.s_addr = inet_addr(ip.c_str());messages = "服務端的輸出結果:"+messages;sendto(fd, messages.c_str(), messages.size(), 0,(struct sockaddr *)&client, len);}
int main(int argc, char *argv[])
{if (argc != 2){cout << "輸入錯誤,請重新輸入" << endl;}uint16_t port = atoi(argv[1]);//openfile();//printdict();unique_ptr<udpServer> server(new udpServer(port, callback));server->init();server->start();return 0;
}

?udpServer.hpp

#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <functional>
#include"userManager"
#include<pthread.h>
using namespace std;const static string defaultip = "0.0.0.0";
// typedef function<void(int,string,uint16_t,string)> func_t;
typedef void (*func_t)(int,string,uint16_t,string);
class udpServer
{
public:udpServer(uint16_t port,func_t callback) : _port(port),_callback(callback){}void init(){// 創建套接字返回fd_fd = socket(AF_INET, SOCK_DGRAM, 0);if (_fd == -1){cerr << "socket error:" << errno << ":" << strerror(errno) << endl;exit(1);}// 將fd和ip,port進行綁定struct sockaddr_in sock;sock.sin_family = AF_INET;sock.sin_port = htons(_port);sock.sin_addr.s_addr = INADDR_ANY;int n = bind(_fd, (struct sockaddr *)&sock, sizeof(sock));if (n == -1){cerr << "bind error:" << errno << ":" << strerror(errno) << endl;exit(2);}}void start(){char buffer[1024];size_t len = sizeof(buffer);char writer[1024];struct sockaddr_in clientsock;socklen_t clientlen = sizeof(clientsock);while (1){size_t n = recvfrom(_fd, buffer, len-1, 0, (struct sockaddr *)&clientsock, &clientlen);if (n > 0){buffer[n]=0;string ip = inet_ntoa(clientsock.sin_addr); // uint32_t->stringuint16_t port = ntohs(clientsock.sin_port);string messages = buffer;cout << ip << "[" << port << "]" << "#" << messages << endl;_callback(_fd,ip,port,messages);}}}~udpServer() {}private:int _fd;uint16_t _port;string _ip;pthread_t writer;func_t _callback;
};

?makefile

cc=g++
.PHONY:all
all:udpClient udpServerudpClient:udpClient.cc$(cc) -o $@ $^ -std=c++11 -lpthread
udpServer:udpServer.cc$(cc) -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:rm -f udpClient udpServer

以下是拓展的代碼:

群聊:userManager

#pragma once
#include <iostream>
#include <string>
#include <unordered_map>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <arpa/inet.h>
#include <strings.h>
#include <netinet/in.h>
#include <functional>
using namespace std;
class User
{
public:User(std::string ip, uint16_t port) : _ip(ip), _port(port){}~User(){}std::string _ip;int16_t _port;
};
class onlineUser
{
public:onlineUser() {}~onlineUser() {}void addOnlineUser(std::string ip, uint16_t port){string id = ip + "[" + std::to_string(port) + "]#";onUser.insert(make_pair(id, User(ip, port)));}void offOnlineUser(std::string ip, uint16_t port){string id = ip + "[" + std::to_string(port) + "]#";onUser.erase(id);}void broadcastMessage(int sockfd, const string &ip, const int16_t &port, const string &messages){string id = ip + "[" + std::to_string(port) + "]#";for (auto &user : onUser){if (user.first != id){sockaddr_in usersock;usersock.sin_family = AF_INET;usersock.sin_port = htons(user.second._port);usersock.sin_addr.s_addr = inet_addr(user.second._ip.c_str());string sendmessage = id + messages;sendto(sockfd, sendmessage.c_str(), sendmessage.size(), 0, (struct sockaddr *)&usersock, sizeof(usersock));}}}private:unordered_map<string, User> onUser;
};

?字典:dict.txt

hello:你好
why:為什么
so:所以
then:然后

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62587.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62587.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62587.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【上線文檔】系統上線方案模板,計算機系統上線保障計劃,系統運維信息系統運行保障方案,系統上線方案模板(Word原件)

一、項目背景和目標 二、項目需求分析 2.1 功能需求 2.2 非功能需求 三、系統設計 3.1 系統架構設計 3.2 數據庫設計 3.3 接口設計 3.4 用戶界面設計 四、系統開發 4.1 開發環境搭建 4.2 業務邏輯開發 4.3 數據庫實現 4.4 接口實現 4.5 用戶界面實現 五、系統測…

大模型應用的數字能源數據集

除了尚須時日的量子計算解決算力效率和能源問題&#xff0c;以及正在路上的超越transformer的全新模型架構外&#xff0c;無疑是“數據集”&#xff0c;準確講是“高質量大規模多樣性的數據集”。數據集是大模型發展的核心要素之一&#xff0c;是大計算的標的物&#xff0c;是實…

【OpenCV】圖像轉換

理論 傅立葉變換用于分析各種濾波器的頻率特性。對于圖像&#xff0c;使用 2D離散傅里葉變換&#xff08;DFT&#xff09; 查找頻域。快速算法稱為 快速傅立葉變換&#xff08;FFT&#xff09; 用于計算DFT。 Numpy中的傅立葉變換 首先&#xff0c;我們將看到如何使用Numpy查…

如何使用Java編寫Jmeter函數

Jmeter 自帶有各種功能豐富的函數&#xff0c;可以幫助我們進行測試&#xff0c;但有時候提供的這些函數并不能滿足我們的要求&#xff0c;這時候就需要我們自己來編寫一個自定義的函數了。例如我們在測試時&#xff0c;有時候需要填入當前的時間&#xff0c;雖然我們可以使用p…

【2024版】最新kali linux入門及常用簡單工具介紹(非常詳細)從零基礎入門到精通,看完這一篇就夠了

前言 相信很多同學了解到和學習網絡安全的時候都聽過kali系統&#xff0c;大家都稱之為黑客最喜愛的系統&#xff0c;那么什么是kali&#xff0c;初學者用kali能做些什么&#xff0c;大白我將在本文中做詳細的介紹&#xff1a; 一、kali linux是什么&#xff1f; Kali Linux…

使用 electron 把 vue 項目打包成客戶端

1. 新建一個Vue項目 新建一個vue項目&#xff0c;或者在已經寫好的vue項目上操作 2. 安裝依賴包 需要安裝的包有2個 electron electron-builder 安裝失敗的&#xff0c;可看另外一篇解決方法https://blog.csdn.net/Anorry/article/details/144061069?spm1001.2014.3001.5501 3…

六大排序算法:插入排序、希爾排序、選擇排序、冒泡排序、堆排序、快速排序

本章講述數據結構中的六大排序算法 歡迎大佬們踴躍討論&#xff0c;感謝大家支持&#xff01; 我的博客主頁鏈接 六大排序算法 一.插入排序1.1 直接插入排序1.2 希爾排序 二.選擇排序2.1 單向選擇排序2.2雙向選擇排序2.3 堆排序 三.交換排序3.1 冒泡排序3.2 快速排序3.2.1 Hoa…

el-table手動觸發懶加載

二次修改了一下&#xff0c;確保點擊某一單元格格元素觸發 // 隱藏懶加載箭頭后手動觸發懶加載 expandRows(scope){scope.row.isExpanded !scope.row.isExpanded // 切換展開狀態let isExpanded scope.row.isExpandedconst { table: { toggleRowExpansion, store }} this.$r…

【MySQL】數據庫 Navicat 可視化工具與 MySQL 命令行基本操作

&#x1f4af; 歡迎光臨清流君的博客小天地&#xff0c;這里是我分享技術與心得的溫馨角落 &#x1f4af; &#x1f525; 個人主頁:【清流君】&#x1f525; &#x1f4da; 系列專欄: 運動控制 | 決策規劃 | 機器人數值優化 &#x1f4da; &#x1f31f;始終保持好奇心&…

threejs相機輔助對象cameraHelper

為指定相機創建一個輔助對象&#xff0c;顯示這個相機的視錐。 想要在場景里面顯示相機的視錐&#xff0c;需要創建兩個相機。 舉個例子&#xff0c;場景中有個相機A&#xff0c;想要顯示相機A的視錐&#xff0c;那么需要一個相機B&#xff0c;把B放在A的后面&#xff0c;兩個…

反向代理-緩存篇

文章目錄 強緩存一、Expires(http1.0 規范)二、cache-control(http1.1 出現的 header 信息)Cache-Control 的常用選項Cache-Control 常用選項的選擇三、弊端協商緩存一、ETag二、If-None-Match三、Last-modified四、If-Modified-Since瀏覽器的三種刷新方式靜態資源部署策略…

深度學習小麥頭檢測-基于Faster-RCNN的小麥頭檢測——附項目源碼

比賽描述 為了獲得有關全世界麥田的大量準確數據,植物科學家使用“小麥頭”(包含谷物的植物上的穗)的圖像檢測。這些圖像用于估計不同品種的小麥頭的密度和大小。但是,在室外野外圖像中進行準確的小麥頭檢測可能在視覺上具有挑戰性。密集的小麥植株經常重疊,并且風會使照片…

健康管理系統(Koa+Vue3)

系統界面(源碼末尾獲取) 系統技術 Vue3 Koa Nodejs Html Css Js ....... 系統介紹 系統比較簡單,輕輕松松面對結業課堂作業.采用的是基于nodejs開發的Koa框架作為后端,采用Vue框架作為前端,完成快速開發和界面展示. 系統獲取 啊啊啊寶/KoaVue3https://gitee.com/ah-ah-b…

數據清洗代碼:缺失值,異常值,離群值Matlab處理

目錄 基本介紹程序設計參考資料基本介紹 一、過程概述 本過程適用于處理SCADA系統采集到的數據,以及具有類似需求的數據集。處理步驟包括缺失值處理、異常值處理和離群值處理,旨在提升數據質量,增強數據的相關性,同時保持數據的原始特征和隨機性。 二、缺失值處理 對于SC…

Leetcode 每日一題 202.快樂數

目錄 題意 算法思路 過題圖片 算法實現 代碼解析 復雜度分析 題目鏈接 結論 題意 判斷正整數 n 是不是快樂數。 快樂數定義&#xff1a; &#xff08;1&#xff09;每次將正整數替換為它每個位置上的數字的平方和。 &#xff08;2&#xff09;重復這個過程直到這個數…

【鴻蒙生態崛起】開發者如何把握機遇,應對挑戰,打造卓越應用體驗?

文章目錄 每日一句正能量前言鴻蒙簡析鴻蒙生態的認知和了解鴻蒙生態的崛起分析 鴻蒙生態下開發時遇到的挑戰開發工具不完善技術難度生態競爭抓住機遇、應對挑戰 鴻蒙生態未來的發展趨勢1. 全場景智慧生活的推動者2. 技術創新的引領者3. 開放合作的倡導者對鴻蒙生態和開發者的建…

Nignx部署Java服務測試使用的Spring Boot項目Demo

天行健&#xff0c;君子以自強不息&#xff1b;地勢坤&#xff0c;君子以厚德載物。 每個人都有惰性&#xff0c;但不斷學習是好好生活的根本&#xff0c;共勉&#xff01; 文章均為學習整理筆記&#xff0c;分享記錄為主&#xff0c;如有錯誤請指正&#xff0c;共同學習進步。…

文本域設置高度 加上文字限制并show出來:

文本域設置高度 :rows"4" 加上文字限制并show出來&#xff1a; maxlength"30" show-word-limit 效果: <el-form-item label"產品備注" prop"remark"><el-input v-model"form.remark" type"textarea"…

區塊鏈軟件系統海外宣發:全球化市場中的策略與實施

隨著區塊鏈技術的快速發展&#xff0c;越來越多的區塊鏈軟件系統進入全球市場&#xff0c;涉及加密貨幣、智能合約、去中心化金融&#xff08;DeFi&#xff09;、供應鏈管理等多個行業應用。為了在激烈的競爭中脫穎而出&#xff0c;區塊鏈軟件系統不僅需要具備卓越的技術能力&a…

springboot413福泰軸承股份有限公司進銷存系統(論文+源碼)_kaic

摘 要 使用舊方法對福泰軸承股份有限公司進銷存系統的信息進行系統化管理已經不再讓人們信賴了&#xff0c;把現在的網絡信息技術運用在福泰軸承股份有限公司進銷存系統的管理上面可以解決許多信息管理上面的難題&#xff0c;比如處理數據時間很長&#xff0c;數據存在錯誤不…