Socket UDP C++
一、
1.此协议也是传输层的协议;
2.此协议是无连接,即就是在传输数据的时候,不需要建立连接,而是直接传输;
3.此协议不保证可靠传输,即就是在传输数据时,不负责传输的数据的正确性,只是单纯的一个传输而已;
4.此协议是面向数据报的,即就是在传输数据时是一下把整个文件传输的,例如某文件大小为10k,此协议在传输时,是一次传输完毕的。
二、
#ifndef SOCKETUDP_H #define SOCKETUDP_H #include <QObject> #include <thread> #include <winsock2.h> using namespace std; class SocketUdp : public QObject { Q_OBJECT public: explicit SocketUdp(QObject *parent = nullptr); signals: void sigRecSocketData(char* data,int dataSize); public slots: public: int connectLocal(const char* ip, const int port); int connectRemote(const char* ip, const int port); int sendData2(char *data,int dataSize); int sendData(char *data,int dataSize); void runRec(); int close(); void exit(); private: SOCKET socketRec_; SOCKET socketSend_; SOCKADDR_IN remoteRecAddr_,localAddr_; SOCKADDR_IN sendAddr_; bool isExitRec_; bool isLocalConnect_; bool isRemoteConnect_; bool recOk_; int localPort_; int remotePort_; std::thread recThread_; }; #endif // SOCKETUDP_H
#include "socketudp.h" #include<stdio.h> #include<tchar.h> #include <iostream> #include <windows.h> #include <QDebug> const int REC_BUFFER_SIZE=100; SocketUdp::SocketUdp(QObject *parent) : QObject(parent), isExitRec_(false), isLocalConnect_(false), isRemoteConnect_(false), recOk_(false) { } int SocketUdp::connectLocal(const char* ip, const int port) { localPort_=port; isLocalConnect_=false; WSAData wsd; //初始化信息 //启动Winsock if (WSAStartup(MAKEWORD(2,2),&wsd) != 0) { cout << "WSAStartup Error = " << WSAGetLastError() << endl; return -1; } //创建socket socketRec_ = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if (socketRec_ == SOCKET_ERROR) { cout << "socket Error = " << WSAGetLastError() << endl; return -2; } localAddr_.sin_family = AF_INET; localAddr_.sin_port = htons(port); localAddr_.sin_addr.s_addr = inet_addr(ip); //绑定本地地址到socket if (bind(socketRec_,(SOCKADDR*)&localAddr_,sizeof(localAddr_)) == SOCKET_ERROR) { cout << "bind Error = " << WSAGetLastError() << endl; return -3; } isLocalConnect_=true; return 1; } int SocketUdp::sendData2(char *data, int dataSize) { int ret= sendto(socketRec_,data,dataSize,0,(SOCKADDR*)&remoteRecAddr_,sizeof(SOCKADDR)); //qDebug()<<"send ret:"<<ret; if (ret == SOCKET_ERROR) { cout << "send to Error " << WSAGetLastError() << endl; } return 1; } int SocketUdp::connectRemote(const char *ip, const int port) { remotePort_=port; isRemoteConnect_=false; WSAData wsd; //初始化信息 //启动Winsock if (WSAStartup(MAKEWORD(2,2),&wsd) != 0) { cout << "WSAStartup Error = " << WSAGetLastError() << endl; return -1; } //创建socket socketSend_ = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if (socketSend_ == SOCKET_ERROR) { cout << "socket Error = " << WSAGetLastError() << endl; return -2; } sendAddr_.sin_family = AF_INET; sendAddr_.sin_port = htons(port); sendAddr_.sin_addr.s_addr = inet_addr(ip); isRemoteConnect_=true; return 1; } int SocketUdp::sendData(char *data, int dataSize) { int ret= sendto(socketSend_,data,dataSize,0,(SOCKADDR*)&sendAddr_,sizeof(SOCKADDR)); //qDebug()<<"send ret:"<<ret; if (ret == SOCKET_ERROR) { cout << "send to Error " << WSAGetLastError() << endl; //重新连接 close(); int reConnTimes=0; isRemoteConnect_=false; while(reConnTimes<3&&!isRemoteConnect_) { isRemoteConnect_=connectRemote("127.0.0.1",remotePort_); reConnTimes++; } if(isRemoteConnect_) { ret=sendto(socketSend_,data,dataSize,0,(SOCKADDR*)&sendAddr_,sizeof(SOCKADDR)); if(ret == SOCKET_ERROR) { cout << "resend 3 times,send to Error " << WSAGetLastError() << endl; return -1; } } else { cout << "send error,reconnect 3 times,connect error" <<endl; return -2; } } return 1; } int SocketUdp::close() { isRemoteConnect_=false; isLocalConnect_=false; //closesocket(socketSend_); closesocket(socketRec_); WSACleanup(); } void SocketUdp::exit() { isExitRec_=true; } void SocketUdp::runRec() { recThread_= std::thread([&](){ while(!isExitRec_) { char* recData = new char[REC_BUFFER_SIZE]; int dwSendSize = sizeof(remoteRecAddr_); int recSize = recvfrom(socketRec_,recData,REC_BUFFER_SIZE,0,(SOCKADDR*)&remoteRecAddr_,&dwSendSize); //qDebug()<<"rec size:"<<recSize; if (recSize == SOCKET_ERROR) { cout << "recvfrom Error " << WSAGetLastError() << endl; recOk_=false; } else if (recSize == 0) { recOk_=false; } else { recOk_=true; sigRecSocketData(recData,recSize); delete [] recData; recData=nullptr; } if(!recOk_) { close(); int reConnTimes=0; isLocalConnect_=false; while(reConnTimes<3&&!isLocalConnect_) { isLocalConnect_=connectLocal("127.0.0.1",localPort_); reConnTimes++; } } std::this_thread::sleep_for(std::chrono:: milliseconds (10)); } }); recThread_.detach(); }