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;
    }
  • 相关阅读:
    Response.Redirect 产生的“正在中止线程”错误,不再执行下面语句解决办法
    c#中采用OLEDB方式来读取EXCEL文件和将数据写入EXCEL文件
    https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
    [bzoj2427][HAOI2010]软件安装——强连通分量+树形DP
    [bzoj3931][CQOI2015]网络吞吐量——最短路+网络流
    [bzoj1823][JSOI2010]满汉全席——2-SAT
    [bzoj1486][HNOI2009]最小圈——分数规划+spfa+负环
    [bzoj3532][Sdoi2014]Lis——拆点最小割+字典序+退流
    [bzoj3876][AHOI2014]支线剧情——上下界费用流
    [bzoj2127]happiness——最小割
  • 原文地址:https://www.cnblogs.com/Trony/p/10755482.html
Copyright © 2011-2022 走看看