C++開發的UDP網路通訊工具類(相容window和linux)
阿新 • • 發佈:2018-12-08
前段時間做專案用到了網路通訊,自己造了UDP通訊的輪子,能同時在window和linux下執行,並且封裝成類,方便以後使用,考慮到自己也一直在網際網路上獲取資源,現在也把我做的輪子也分享給大家,歡迎參考~
完整程式碼附在下面,如果大家不想複製,可直接從這下載:https://download.csdn.net/download/qq_18108083/10798492
(1)XUdp.h
#ifndef XUDP_H #define XUDP_H #ifdef WIN32 #include <windows.h> #define socklen_t int #else #include <arpa/inet.h> #define closesocket close //替換close函式 #include <unistd.h> #endif class XUdp { public: int CreateSocket(); //建立套接字 void Close(); //關閉連線 bool Bind(); //繫結並監聽埠號 int Send(const char *buf, int size, char *ip, unsigned short port); //傳送資料 int Recv(char *buf, int bufsize, sockaddr_in *from); //接收資料 int SetRecvTimeout(int sec); //設定udp接收超時 int SetSendTimeout(int sec); //設定udp傳送超時 XUdp(unsigned short port = 9000); virtual ~XUdp(); private: int usock = 0; //udp服務端的socket create成員函式自己生成 unsigned short uport = 0; //建構函式從外獲取 }; #endif
(2)XUdp.cpp
#include "XUdp.h" #include <iostream> //IO流操作 #include <string> //string標準庫 #ifdef WIN32 #include <windows.h> #define socklen_t int #else #include <arpa/inet.h> #define closesocket close //替換close函式 #include <unistd.h> #include <pthread.h> #endif XUdp::XUdp(unsigned short port) { //初始化動態連結庫 //引用lib庫 #ifdef WIN32 //linux下不用初始化網路庫 static bool first = true; if (first) { first = false; //只在首次進入時初始化網路庫 WSADATA ws; //載入Socket庫 專案屬性-連結器-輸入加上 ws2_32.lib WSAStartup(MAKEWORD(2, 2), &ws); //動態庫引用加1 } #endif uport = port; } XUdp::~XUdp() { delete this; } int XUdp::CreateSocket() //建立套接字 { usock = socket(AF_INET, SOCK_DGRAM, 0); //TCP/IP UDP 建立udp 套接字 if (usock == -1) { printf("create udp socket failed.\n"); return -1; } printf("create udp socket success.\n"); return 0; } void XUdp::Close() //關閉連線 { if (usock <= 0) return; //socket出錯 closesocket(usock); //已巨集定義 usock = 0; uport = 0; } bool XUdp::Bind() //繫結並監聽埠號 { sockaddr_in saddr; //資料結構 saddr.sin_family = AF_INET; //協議 saddr.sin_port = htons(uport); //埠,主機位元組序(小端方式)轉換成網路位元組序(大端方式) // saddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); saddr.sin_addr.s_addr = htonl(INADDR_ANY); //繫結IP到廣播地址INADDR_ANY 0.0.0.0 為了相容linux if (bind(usock, (sockaddr*)&saddr, sizeof(saddr)) != 0) //安裝sockaddr_in資料結構繫結套接字 { printf("udp bind port %d failed.\n", uport); return false; } printf("udp bind port %d success.\n", uport); return true; } int XUdp::Send(const char *buf, int size, char *ip, unsigned short port) //傳送資料(強制全部發送) { int sendedSize = 0; //已傳送成功的長度 sockaddr_in saddr; saddr.sin_family = AF_INET; //tcp/ip協議 saddr.sin_port = htons(port);//服務端的埠 主機位元組序轉換成網路位元組序 saddr.sin_addr.s_addr = inet_addr(ip); //本機的ip地址 字串ip地址轉成整型 while (sendedSize != size) //若沒傳送完成,則從斷點開始繼續傳送 直到完成 { int len = sendto(usock, buf + sendedSize, size - sendedSize, 0, (sockaddr*)&saddr, sizeof(saddr)); if (len <= 0)break; sendedSize += len; } return sendedSize; } int XUdp::Recv(char *buf, int bufsize, sockaddr_in *from) //接收資料 { socklen_t len = sizeof(sockaddr_in); int re = recvfrom(usock, buf, bufsize, 0, (sockaddr*)from, &len); //返回接收的客戶端的網路地址,存在在地址中 return re; } int XUdp::SetRecvTimeout(int sec = 1) //設定udp接收超時 { #ifdef WIN32 int udp_rev_time = sec * 1000; if (setsockopt(usock, SOL_SOCKET, SO_RCVTIMEO, (char *)&udp_rev_time, sizeof(int))<0) { printf("set udp receive failed.\n"); return -1; } printf("set udp recv timeout success. %d seconds\n", sec); return 0; #else struct timeval udp_rev_time; udp_rev_time.tv_sec = sec; udp_rev_time.tv_usec = 0; if (setsockopt(usock, SOL_SOCKET, SO_RCVTIMEO, (char *)&udp_rev_time, sizeof(udp_rev_time))<0) { printf("set udp receive failed.\n"); return -1; } printf("set udp recv timeout success. %d seconds\n", sec); return 0; #endif } int XUdp::SetSendTimeout(int sec = 1) //設定udp傳送超時 { #ifdef WIN32 int udp_rev_time = sec; if (setsockopt(usock, SOL_SOCKET, SO_SNDTIMEO, (char *)&udp_rev_time, sizeof(int))<0) { printf("set udp send failed."); return -1; } return 0; printf("set udp send timeout success. %d seconds\n", sec); #else struct timeval udp_rev_time; udp_rev_time.tv_sec = sec; udp_rev_time.tv_usec = 0; if (setsockopt(usock, SOL_SOCKET, SO_SNDTIMEO, (char *)&udp_rev_time, sizeof(udp_rev_time))<0) { printf("set udp send failed."); return -1; } printf("set udp send timeout success. %d seconds\n", sec); return 0; #endif }