• [VC++] socket网络传输


    不研究TCP/IP协议,没有三次握手,不说 物数网传会表应(只要大学学过计算机基础的都背过吧!)这七层。

    封装好socket。

    server:

    class ServerSock
    {
    public:
        ServerSock();
        ~ServerSock();
        SOCKET getClient() {return sClient;};
    
    private:
        static const int PORT = 10086;
        int             retVal;         //返回值 
        SOCKET          sServer;        //服务器套接字  
        SOCKET          sClient;        //客户端套接字  
        SOCKADDR_IN     addrServ;;      //服务器地址  
    };
    
    ServerSock::ServerSock()
    {
        WSADATA wsd;            //WSADATA变量  
        //初始化套结字动态库  
        if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)  
        {  
            cout << "WSAStartup failed!" << endl;  
        }  
        //创建套接字  
        sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);      
        if(INVALID_SOCKET == sServer)  
        {  
            cout << "socket failed!" << endl;  
            WSACleanup();//释放套接字资源;  
        }  
        //服务器套接字地址   
        addrServ.sin_family = AF_INET;  
        addrServ.sin_port = htons(PORT);  
        addrServ.sin_addr.s_addr = INADDR_ANY;        
        //绑定套接字  
        retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));  
        if(SOCKET_ERROR == retVal)  
        {     
            cout << "bind failed!" << endl;  
            closesocket(sServer);   //关闭套接字  
            WSACleanup();           //释放套接字资源;  
        }  
        //开始监听   
        cout<<"start listen!"<<endl;
        retVal = listen(sServer, 1);  
        if(SOCKET_ERROR == retVal)  
        {  
            cout << "listen failed!" << endl;         
            closesocket(sServer);   //关闭套接字  
            WSACleanup();           //释放套接字资源;  
        }  
        //接受客户端请求  
        sockaddr_in addrClient;  
        int addrClientlen = sizeof(addrClient);  
        sClient = accept(sServer,(sockaddr FAR*)&addrClient, &addrClientlen);  
        cout<<"accept!"<<endl;
        if(INVALID_SOCKET == sClient)  
        {  
            cout << "accept failed!" << endl;         
            closesocket(sServer);   //关闭套接字  
            WSACleanup();           //释放套接字资源;  
        } 
    }
    
    ServerSock::~ServerSock()
    {
        closesocket(sServer);   //关闭套接字  
        //closesocket(sClient);   //关闭套接字  
        WSACleanup();            //释放套接字资源;  
    }

    client:

    class ClientSock
    {
    public:
        ClientSock();
        ~ClientSock();
        SOCKET getClient() {return cClient;};
    
    private:
        static const int PORT = 10086;
        int             retVal;         //返回值 
        SOCKET          cClient;        //客户端套接字  
        SOCKADDR_IN     addrServ;;      //服务器地址  
    };
    
    ClientSock::ClientSock()
    {
        WSADATA wsd;            //WSADATA变量  
        //初始化套结字动态库  
        if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)  
        { 
            cout << "WSAStartup failed!" << endl;  
        }  
        //创建套接字  
        cClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);      
        if(INVALID_SOCKET == cClient)  
        {  
            cout << "socket failed!" << endl;  
            WSACleanup();//释放套接字资源;  
        }  
        //服务器套接字地址   
        addrServ.sin_family = AF_INET;  
        addrServ.sin_port = htons(PORT);  
        addrServ.sin_addr.s_addr = inet_addr(IP_ADDR);        
        //绑定套接字  
        retVal = connect(cClient, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));  
        if(SOCKET_ERROR == retVal)  
        {     
            cout << "connect failed!" << endl;  
            closesocket(cClient);   //关闭套接字  
            WSACleanup();           //释放套接字资源;  
        }  
    }
    
    ClientSock::~ClientSock()
    {
        //closesocket(cClient);   //关闭套接字  
        WSACleanup();            //释放套接字资源;  
    }

    关于数据部分,两个是通用的

    class SockData
    {
    public:
        SockData(SOCKET _client) { client = _client;};
        ~SockData()  { closesocket(client); };
        bool sendData(const char sData);
        bool sendData(int sData);
        bool sendData(char* sData,int Len = BUFSIZE);
        bool sendData(const string sfileRoad);
        int recvData();
        bool recvData(char* buf, int Len = BUFSIZE);
        bool recvData(const string rfileRoad);
    
    private:
        static const int BUFSIZE = 1024;        //默认大小
        int             retVal;         //返回值 
        SOCKET          client;        //客户端套接字  
    };
    
    
    bool SockData::sendData(const char sData)
    {
        retVal = send(client,&sData,sizeof(char),0);
        if(retVal==SOCKET_ERROR)
        {
            cout<<"Send Into error: "<<GetLastError()<<endl;
            cout<<"Fail char: "<<sData<<endl;
            return false;
        }
        return true;
    }
    
    bool SockData::sendData(int sData)
    {
        stringstream strTemp;strTemp.clear();strTemp.str("");
        strTemp << sData;
        const string sTemp = strTemp.str();
        const char* cTemp = sTemp.c_str();
        if(! sendData(char('0'+strlen(cTemp))))
        {
            cout<<"In trouble"<<endl;
        }
        retVal = send(client,cTemp,sizeof(char) * strlen(cTemp),0);
        if(retVal==SOCKET_ERROR)
        {
            cout<<"Send Into error: "<<GetLastError()<<endl;
            cout<<"Fail int: "<<sData<<endl;
            return false;
        }
        return true;
    }
    
    bool SockData::sendData(char* sData,int Len)
    {
        retVal=send(client,sData,sizeof(char) * Len,0);
        if(retVal==SOCKET_ERROR)
        {
            cout<<"Send Into error: "<<GetLastError()<<endl;
            return false;
        }
        return true;
    }
    
    bool SockData::sendData(const string sfileRoad)
    {
        ifstream in(sfileRoad,fstream::in|fstream::binary);
        if(!in.is_open())
        {
            cout<<"fail open file."<<endl;
            return false;
        }
        in.seekg (0, ios::end);  
        int length = in.tellg();  
        in.seekg (0, ios::beg); 
    
        sendData(length);
        char* buf = new char[BUFSIZE];  //接收数据缓冲区  
        ZeroMemory(buf, BUFSIZE);
    
        while(!in.eof())
        {
            in.read(buf,BUFSIZE);
            retVal=send(client,buf,sizeof(char) * BUFSIZE,0);
            if(retVal==SOCKET_ERROR)
            {
                cout<<"Send Into error: "<<GetLastError()<<endl;
                return false;
            }
        }
        in.close();
        delete[] buf;
    
        return true;
    }
    
    int SockData::recvData()
    {
        char intBit;
        retVal = recv(client,&intBit,sizeof(char),0);
        if(retVal == SOCKET_ERROR)
        {
            cout<<"Recv Into error: "<<GetLastError()<<endl;
            cout<<"Fail intBit!"<<endl;
            return false;
        }
        int Bit = atoi(&intBit);
        char* cInt = new char[Bit];
        retVal = recv(client,cInt,sizeof(char) * Bit,0);
        if(retVal == SOCKET_ERROR)
        {
            cout<<"Recv Into error: "<<GetLastError()<<endl;
            cout<<"Fail intBit!"<<endl;
            return false;
        }
        int rData = atoi(cInt);
        delete[] cInt;
    
        return rData;
    }
    
    bool SockData::recvData(char* buf, int Len)
    {
        ZeroMemory(buf,Len);
        if(Len <= BUFSIZE)
        {
            retVal = recv(client,buf,sizeof(char) * Len,0);
            if(retVal == SOCKET_ERROR)
            {
                cout<<"Recv Into error: "<<GetLastError()<<endl;
                cout<<"Fail char*!"<<endl;
                return false;
            }
        }
        else
        {
            int rbufReal = 0, rbufNeed = Len;
            while (rbufReal < Len)
            {
                retVal = recv(client,buf,sizeof(char) * BUFSIZE,0);
                if(retVal == SOCKET_ERROR)
                {
                    cout<<"Recv Into error: "<<GetLastError()<<endl;
                    cout<<"Fail char*!"<<endl;
                    return false;
                }
                rbufReal += retVal;
                rbufNeed = Len - rbufReal;
            }
        }
    
        return true;
    }
    
    bool SockData::recvData(const string rfileRoad)
    {
        int length = recvData();
        char* buf = new char[BUFSIZE];
        ZeroMemory(buf, BUFSIZE);
        ofstream out(rfileRoad,fstream::out|fstream::binary);
        if(!out.is_open())
        {
            cout<<"don't create file."<<endl;
            return false;
        }
        int rbufReal = 0, rbufNeed = length;
        while (rbufReal < length)
        {
            if(recvData(buf))
            {
                rbufReal += retVal;
                rbufNeed = length - rbufReal;
                out.write(buf,sizeof(char)*retVal);
            }
        }    
        out.close();
        delete[] buf;
    
        return true;
    }

    代码托管:https://github.com/zhanxiage1994/VCplusSocket.git

  • 相关阅读:
    Redis使用小结
    MongoDB中的变更通知
    发布一个从迅雷下载字幕的小工具
    在Windows下通过netsh命令实现端口映射
    .net core在Linux ARM板上运行
    通过WinAPI播放PCM声音
    spring中scope作用域(转)
    Spring <context:annotation-config/> 解说(转)
    Jenkins+Maven+SVN快速搭建持续集成环境(转)
    maven中跳过单元测试(转)
  • 原文地址:https://www.cnblogs.com/zhanxiage1994/p/6674108.html
Copyright © 2020-2023  润新知