zoukankan      html  css  js  c++  java
  • c++实现对windwos 下socket 的封装(实现封包及拆包处理)

     1 SuperSocket.h
     2 
     3 #pragma once
     4 #include<string>
     5 #include<iostream>
     6 #include <WINSOCK2.H>
     7 #include "MyThread.h"
     8 #include "SuperThread.h"
     9 using namespace std;
    10 class SuperSocket
    11 {
    12 public:
    13     typedef struct SockData{
    14         int id;
    15         int length;
    16         const char* content;
    17     }SockData;
    18 public:
    19     void Listen(int port);
    20     bool Connect(string ipStr,int port);
    21     void Send(SockData* data);
    22 protected:
    23     virtual void OnAccept(SOCKET* socket){};
    24     void RollReceive();
    25     void ListenThread();
    26     int port;
    27     virtual void OnReceive(SockData* data){};
    28     SOCKET tempSocket;
    29     SuperThread<SuperSocket>* mt;
    30 };

    SuperSocket.cpp

      1 #include "SuperSocket.h"
      2 
      3 
      4 void SuperSocket::ListenThread()
      5 {
      6     WORD wVersionRequested;// 定义版本信息变量
      7     WSADATA wsaData;//定义数据信息变量
      8     SOCKET sockfd;
      9     struct sockaddr_in server_addr;
     10     struct sockaddr_in client_addr;
     11     
     12     int err;//定义错误号变量
     13     wVersionRequested = MAKEWORD(1,1);//给版本信息赋值
     14     err = WSAStartup(wVersionRequested, &wsaData);//给错误信息赋值
     15     if(err!=0)
     16     {
     17         return;//告诉用户找不到合适的版本
     18     }
     19     //确认 Windows Sockets DLL 支持 1.1 版本
     20     //DLL 版本可以高于 1.1
     21     //系统返回的版本号始终是最低要求的 1.1,即应用程序与DLL 中可支持的最低版本号
     22     if(LOBYTE(wsaData.wVersion)!= 1||HIBYTE(wsaData.wVersion)!=1)
     23     {
     24         WSACleanup();//告诉用户找不到合适的版本
     25         return;
     26     }
     27     
     28     if((sockfd=socket(AF_INET,SOCK_STREAM, IPPROTO_TCP))==-1) 
     29     {
     30         if (WSAGetLastError() == WSANOTINITIALISED)
     31         {
     32             printf("Error:WSANOTINITIALISED,please Call WSAStartup first
    ");
     33             return;
     34         }
     35         else
     36         {
     37             int err =WSAGetLastError();
     38             printf("Bind error:%s,errorcode :%d
    ",strerror(errno),err);
     39             return;
     40         }
     41     }
     42     
     43     /* 服务器端填充 sockaddr结构 */ 
     44     memset(&server_addr,0,sizeof(struct sockaddr_in));
     45     server_addr.sin_family=AF_INET;
     46     server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
     47     server_addr.sin_port=htons(port);
     48     
     49     /* 捆绑sockfd描述符 */ 
     50     if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
     51     {
     52         int err = WSAGetLastError();
     53         cout<<"Bind error:%s,errorcode :"<<strerror(errno)<<endl;;
     54         return;
     55     }
     56     
     57     /* 监听sockfd描述符 */
     58     if(listen(sockfd,5)==-1)
     59     {
     60         cout<<"Listen error:"<<strerror(errno)<<endl;
     61         return;
     62     }
     63     while(1)
     64     {
     65         /* 服务器阻塞,直到客户程序建立连接 */
     66         int sin_size=sizeof(struct sockaddr_in);
     67         SOCKET socket;
     68         cout<<"I am Listen ....."<<endl;
     69         if((socket=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==INVALID_SOCKET )
     70         {
     71             cout<<"Accept error:"<<strerror(errno)<<endl;;
     72             continue;
     73         }
     74         cout<<"Server get connection from "<<inet_ntoa(client_addr.sin_addr)<<endl;;
     75         this->OnAccept(&socket);
     76     }
     77 }
     78 void SuperSocket::Listen(int port)
     79 {
     80     this->port=port;
     81     //    MyThread mt;
     82     //    mt.InitThread(this,&SuperSocket::ListenThread);
     83     //    mt.StartThread();
     84     this->mt=new SuperThread<SuperSocket>(this,&SuperSocket::ListenThread);
     85     this->mt->StartThread();
     86 }
     87 
     88 bool SuperSocket::Connect(string ipStr,int port)
     89 {
     90     WSADATA  Ws;
     91     SOCKET CientSocket;
     92     struct sockaddr_in ServerAddr;
     93     int AddrLen = 0;
     94     HANDLE hThread = NULL;
     95     
     96     //Init Windows Socket
     97     if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )
     98     {
     99         cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
    100         return false;
    101     }
    102     
    103     //Create Socket
    104     CientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    105     if ( CientSocket == INVALID_SOCKET )
    106     {
    107         cout<<"Create Socket Failed::"<<GetLastError()<<endl;
    108         return false;
    109     }
    110     
    111     ServerAddr.sin_family = AF_INET;
    112     ServerAddr.sin_addr.s_addr = inet_addr(ipStr.c_str());
    113     ServerAddr.sin_port = htons(port);
    114     memset(ServerAddr.sin_zero, 0x00, 8);
    115 
    116     int err = connect(CientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr));
    117     if ( err == SOCKET_ERROR )
    118     {
    119         cout<<"Connect Error::"<<GetLastError()<<endl;
    120         return false;
    121     }
    122     else
    123     {
    124     //    MyThread mt;
    125     //    mt.InitThread(this,&SuperSocket::RollReceive);
    126     //    mt.StartThread();
    127         this->tempSocket=CientSocket;
    128         SuperThread<SuperSocket> st(this,&SuperSocket::RollReceive);
    129         st.StartThread();
    130         return true;
    131     }
    132 }
    133 
    134 void SuperSocket::RollReceive()
    135 {
    136     int iResult;
    137     int recvbuflen=1024;
    138     bool isComplete=true;
    139     int ID;
    140     int length;
    141     int lenReaded;
    142     int lenLeaved;
    143     char content[100000];
    144     while(true)
    145     {
    146         if(!isComplete)
    147         {
    148             
    149             iResult=recv(tempSocket,content+lenReaded,lenLeaved,0);
    150             if(iResult<=0)
    151             {
    152                 printf("recv failed with error: %d/n", WSAGetLastError());  
    153                 closesocket(this->tempSocket);  
    154                 break;
    155             }
    156             lenReaded+=iResult;
    157             lenLeaved=length-lenReaded;
    158             if(lenReaded<length)
    159             {
    160                 isComplete=false;
    161             }
    162         }
    163         else
    164         {
    165             iResult=recv(tempSocket,(char*)&ID,sizeof(int),0);
    166             if(iResult<=0)
    167             {
    168                 printf("recv failed with error 0: %d/n", WSAGetLastError());  
    169                 closesocket(this->tempSocket);  
    170                 break;
    171             }
    172             iResult=recv(tempSocket,(char*)&length,sizeof(int),0);
    173             if(iResult!=sizeof(int))
    174             {
    175                 printf("recv failed with error 1: %d/n", WSAGetLastError());  
    176                 closesocket(this->tempSocket);  
    177                 break;
    178             }
    179             memset(content,0,length+1);
    180             iResult=recv(tempSocket,content,length,0);
    181             if(iResult<=0)
    182             {
    183                 printf("recv failed with error 2: %d/n", WSAGetLastError());  
    184                 closesocket(this->tempSocket);  
    185                 break;
    186             }
    187             lenReaded=length;
    188             lenLeaved=length-lenReaded;
    189             if(iResult<length)
    190             {
    191                 isComplete=false;
    192             }
    193         }
    194         if(lenLeaved<=0)
    195         {
    196             isComplete=true;
    197             SuperSocket::SockData sockData;
    198             sockData.id=ID;
    199             sockData.length=length;
    200             sockData.content=content;
    201             this->OnReceive(&sockData);
    202         }        
    203     }
    204 }
    205 
    206 void SuperSocket::Send(SuperSocket::SockData* data)
    207 {
    208     send(tempSocket,(char*)&data->id,sizeof(int),0);
    209     send(tempSocket,(char*)&data->length,sizeof(int),0);
    210     send(tempSocket,data->content,data->length,0);
    211 }

    SuperThread.h

    #include<windows.h>
    
    
    template<typename T>
    class SuperThread
    {
    public:
        SuperThread(T* t,void (T::*f)());
        void StartThread();
        void PauseThread();
        void RestartThread();
        void DestroyThread();
        void WaitForThread();
        static DWORD WINAPI StartRun(void* param);
        T* t;
        void (T::*f)();
        static bool isOk;
    private:
    //    pthread_t mThread;
        HANDLE handle;
        
    
    };
    template<typename T>
    bool SuperThread<T>::isOk=false;
    template<typename T>
    SuperThread<T>::SuperThread(T* t,void (T::*f)())
    {
        this->t=t;
        this->f=f;
    }
    template<typename T>
    void SuperThread<T>::StartThread()
    {
    //    pthread_create(&mThread,NULL,&StartRun,this);
        handle=CreateThread(NULL,0,StartRun,this,0,0);
        while(!this->isOk)
        {
            Sleep(50);
        }
        this->isOk=false;
    //    WaitForSingleObject(hMutex,INFINITE);
    
    
    }
    template<typename T>
    void SuperThread<T>::PauseThread()
    {
    }
    template<typename T>
    void SuperThread<T>::RestartThread()
    {
    }
    template<typename T>
    void SuperThread<T>::DestroyThread()
    {
    
    }
    template<typename T>
    void SuperThread<T>::WaitForThread()
    {
        //pthread_join(mThread,NULL);
        WaitForSingleObject(handle,INFINITE);
    }
    template<typename T>
    DWORD WINAPI SuperThread<T>::StartRun(void* param)
    {
        SuperThread<T>* mt=(SuperThread<T>*) param;
        T *t1=mt->t;
        void (T::*f1)();
        f1=mt->f;
        SuperThread<T>::isOk=true;
        (t1->*f1)();
        return 0;
    }

    MySocket.h

    #include "SuperSocket.h"
    
    class MySocket:public SuperSocket
    {
    public:
        MySocket(SOCKET* socket);
        MySocket(){}
    protected:
        virtual void OnAccept(SOCKET* socket);
        virtual void OnReceive(SuperSocket::SockData* data);
    };

    MySocket.cpp

     1 #include "MySocket.h"
     2 #include "MyThread.h"
     3 
     4 void MySocket::OnAccept(SOCKET* socket)
     5 {
     6     SuperSocket* ss=new MySocket(socket);
     7     //MyThread* mt=new MyThread(&ms,MySocket::RollReceive);
     8 //    MyThread mt;
     9 //    mt.InitThread(ss,&SuperSocket::RollReceive);
    10 //    mt.StartThread();
    11     SuperThread<SuperSocket> st(ss,&SuperSocket::RollReceive);
    12     st.StartThread();
    13 }
    14 
    15 MySocket::MySocket(SOCKET* socket)
    16 {
    17     this->tempSocket=*socket;
    18 }
    19 
    20 void MySocket::OnReceive(SuperSocket::SockData* data)
    21 {
    22     cout<<data->id<<endl;
    23 }

    main.cpp

    #include<iostream>
    #include<string>
    #include "MySocket.h"
    using namespace std;
    int main()
    {
        MySocket  ms;
        ms.Connect("10.10.24.148",8010);
        while(true)
        {
            string s;
            cin>>s;
            MySocket::SockData data;
            data.id=0;
            data.length=s.size();
            data.content=s.c_str();
            ms.Send(&data);
        }
        return 0;
    }
  • 相关阅读:
    数据类型装换
    变量及数据类型
    27 网络通信协议 udp tcp
    26 socket简单操作
    26 socket简单操作
    14 内置函数 递归 二分法查找
    15 装饰器 开闭原则 代参装饰器 多个装饰器同一函数应用
    12 生成器和生成器函数以及各种推导式
    13 内置函数 匿名函数 eval,exec,compile
    10 函数进阶 动态传参 作用域和名称空间 函数的嵌套 全局变量
  • 原文地址:https://www.cnblogs.com/Trony/p/10755482.html
Copyright © 2011-2022 走看看