码迷,mamicode.com
首页 > 编程语言 > 详细

c++实现对windwos 下socket 的封装(实现封包及拆包处理)

时间:2019-04-23 13:06:58      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:最低版本   last   typename   描述   支持   tla   windows   memset   监听   

 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\n");
 33             return;
 34         }
 35         else
 36         {
 37             int err =WSAGetLastError();
 38             printf("Bind error:%s,errorcode :%d\n",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;
}

 

c++实现对windwos 下socket 的封装(实现封包及拆包处理)

标签:最低版本   last   typename   描述   支持   tla   windows   memset   监听   

原文地址:https://www.cnblogs.com/Trony/p/10755482.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!