Socket UDP C++

时间:2020-03-08
本文章向大家介绍Socket UDP C++,主要包括Socket UDP C++使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、

二、

#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();

}

原文地址:https://www.cnblogs.com/ike_li/p/12442527.html