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\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; }
标签:socket,int,MySocket,void,c++,拆包,SuperThread,data,SuperSocket 来源: https://www.cnblogs.com/Trony/p/10755482.html