zoukankan      html  css  js  c++  java
  • 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();
    
    }
  • 相关阅读:
    纯CSS打造好看的按钮样式
    jQuery手机端触摸卡片切换效果
    CSS手动改变DIV高宽
    Windows 10 的音频和 MIDI API将统一
    美食网站响应式精美模板
    三道Javascript的练习题
    html5手机端遮罩弹出菜单代码
    CSS的::selection使用方法
    Html5绘制饼图统计图
    JQuery实现一个简单的鼠标跟随提示效果
  • 原文地址:https://www.cnblogs.com/ike_li/p/12442527.html
Copyright © 2011-2022 走看看