SuperSocket.h

 #pragma once
#include<string>
#include<iostream>
#include <WINSOCK2.H>
#include "MyThread.h"
#include "SuperThread.h"
using namespace std;
class SuperSocket
{
public:
typedef struct SockData{
int id;
int length;
const char* content;
}SockData;
public:
void Listen(int port);
bool Connect(string ipStr,int port);
void Send(SockData* data);
protected:
virtual void OnAccept(SOCKET* socket){};
void RollReceive();
void ListenThread();
int port;
virtual void OnReceive(SockData* data){};
SOCKET tempSocket;
SuperThread<SuperSocket>* mt;
};

SuperSocket.cpp

 #include "SuperSocket.h"

 void SuperSocket::ListenThread()
{
WORD wVersionRequested;// 定义版本信息变量
WSADATA wsaData;//定义数据信息变量
SOCKET sockfd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr; int err;//定义错误号变量
wVersionRequested = MAKEWORD(,);//给版本信息赋值
err = WSAStartup(wVersionRequested, &wsaData);//给错误信息赋值
if(err!=)
{
return;//告诉用户找不到合适的版本
}
//确认 Windows Sockets DLL 支持 1.1 版本
//DLL 版本可以高于 1.1
//系统返回的版本号始终是最低要求的 1.1,即应用程序与DLL 中可支持的最低版本号
if(LOBYTE(wsaData.wVersion)!= ||HIBYTE(wsaData.wVersion)!=)
{
WSACleanup();//告诉用户找不到合适的版本
return;
} if((sockfd=socket(AF_INET,SOCK_STREAM, IPPROTO_TCP))==-)
{
if (WSAGetLastError() == WSANOTINITIALISED)
{
printf("Error:WSANOTINITIALISED,please Call WSAStartup first\n");
return;
}
else
{
int err =WSAGetLastError();
printf("Bind error:%s,errorcode :%d\n",strerror(errno),err);
return;
}
} /* 服务器端填充 sockaddr结构 */
memset(&server_addr,,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(port); /* 捆绑sockfd描述符 */
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-)
{
int err = WSAGetLastError();
cout<<"Bind error:%s,errorcode :"<<strerror(errno)<<endl;;
return;
} /* 监听sockfd描述符 */
if(listen(sockfd,)==-)
{
cout<<"Listen error:"<<strerror(errno)<<endl;
return;
}
while()
{
/* 服务器阻塞,直到客户程序建立连接 */
int sin_size=sizeof(struct sockaddr_in);
SOCKET socket;
cout<<"I am Listen ....."<<endl;
if((socket=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==INVALID_SOCKET )
{
cout<<"Accept error:"<<strerror(errno)<<endl;;
continue;
}
cout<<"Server get connection from "<<inet_ntoa(client_addr.sin_addr)<<endl;;
this->OnAccept(&socket);
}
}
void SuperSocket::Listen(int port)
{
this->port=port;
// MyThread mt;
// mt.InitThread(this,&SuperSocket::ListenThread);
// mt.StartThread();
this->mt=new SuperThread<SuperSocket>(this,&SuperSocket::ListenThread);
this->mt->StartThread();
} bool SuperSocket::Connect(string ipStr,int port)
{
WSADATA Ws;
SOCKET CientSocket;
struct sockaddr_in ServerAddr;
int AddrLen = ;
HANDLE hThread = NULL; //Init Windows Socket
if ( WSAStartup(MAKEWORD(,), &Ws) != )
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return false;
} //Create Socket
CientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( CientSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return false;
} ServerAddr.sin_family = AF_INET;
ServerAddr.sin_addr.s_addr = inet_addr(ipStr.c_str());
ServerAddr.sin_port = htons(port);
memset(ServerAddr.sin_zero, 0x00, ); int err = connect(CientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr));
if ( err == SOCKET_ERROR )
{
cout<<"Connect Error::"<<GetLastError()<<endl;
return false;
}
else
{
// MyThread mt;
// mt.InitThread(this,&SuperSocket::RollReceive);
// mt.StartThread();
this->tempSocket=CientSocket;
SuperThread<SuperSocket> st(this,&SuperSocket::RollReceive);
st.StartThread();
return true;
}
} void SuperSocket::RollReceive()
{
int iResult;
int recvbuflen=;
bool isComplete=true;
int ID;
int length;
int lenReaded;
int lenLeaved;
char content[];
while(true)
{
if(!isComplete)
{ iResult=recv(tempSocket,content+lenReaded,lenLeaved,);
if(iResult<=)
{
printf("recv failed with error: %d/n", WSAGetLastError());
closesocket(this->tempSocket);
break;
}
lenReaded+=iResult;
lenLeaved=length-lenReaded;
if(lenReaded<length)
{
isComplete=false;
}
}
else
{
iResult=recv(tempSocket,(char*)&ID,sizeof(int),);
if(iResult<=)
{
printf("recv failed with error 0: %d/n", WSAGetLastError());
closesocket(this->tempSocket);
break;
}
iResult=recv(tempSocket,(char*)&length,sizeof(int),);
if(iResult!=sizeof(int))
{
printf("recv failed with error 1: %d/n", WSAGetLastError());
closesocket(this->tempSocket);
break;
}
memset(content,,length+);
iResult=recv(tempSocket,content,length,);
if(iResult<=)
{
printf("recv failed with error 2: %d/n", WSAGetLastError());
closesocket(this->tempSocket);
break;
}
lenReaded=length;
lenLeaved=length-lenReaded;
if(iResult<length)
{
isComplete=false;
}
}
if(lenLeaved<=)
{
isComplete=true;
SuperSocket::SockData sockData;
sockData.id=ID;
sockData.length=length;
sockData.content=content;
this->OnReceive(&sockData);
}
}
} void SuperSocket::Send(SuperSocket::SockData* data)
{
send(tempSocket,(char*)&data->id,sizeof(int),);
send(tempSocket,(char*)&data->length,sizeof(int),);
send(tempSocket,data->content,data->length,);
}

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,,StartRun,this,,);
while(!this->isOk)
{
Sleep();
}
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 ;
}

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

 #include "MySocket.h"
#include "MyThread.h" void MySocket::OnAccept(SOCKET* socket)
{
SuperSocket* ss=new MySocket(socket);
//MyThread* mt=new MyThread(&ms,MySocket::RollReceive);
// MyThread mt;
// mt.InitThread(ss,&SuperSocket::RollReceive);
// mt.StartThread();
SuperThread<SuperSocket> st(ss,&SuperSocket::RollReceive);
st.StartThread();
} MySocket::MySocket(SOCKET* socket)
{
this->tempSocket=*socket;
} void MySocket::OnReceive(SuperSocket::SockData* data)
{
cout<<data->id<<endl;
}

main.cpp

#include<iostream>
#include<string>
#include "MySocket.h"
using namespace std;
int main()
{
MySocket ms;
ms.Connect("10.10.24.148",);
while(true)
{
string s;
cin>>s;
MySocket::SockData data;
data.id=;
data.length=s.size();
data.content=s.c_str();
ms.Send(&data);
}
return ;
}

c++实现对windwos 下socket 的封装(实现封包及拆包处理)的更多相关文章

  1. js 实现对ajax请求面向对象的封装

             AJAX 是一种用于创建高速动态网页的技术.通过在后台与server进行少量数据交换.AJAX 能够使网页实现异步更新.这意味着能够在不又一次载入整个网页的情况下,对网页的某部分进行 ...

  2. 利用过滤器Filter和特性Attribute实现对Web API返回结果的封装和统一异常处理

    在我们开发Web API应用的时候,我们可以借鉴ABP框架的过滤器Filter和特性Attribute的应用,实现对Web API返回结果的封装和统一异常处理,本篇随笔介绍利用AuthorizeAtt ...

  3. jmeter通过BeanShell 脚本,实现对http请求参数的加密

    jmeter一直是一款很好的接口和性能测试工具,它是开源的,不需要为此支付任何费用,而且可以下载源码,可以在修改源代码并在此基础上拓展自己的功能或插件,它可以跟ant和jenkins结合起来搭建自己的 ...

  4. 基于spring-boot和docker-java实现对docker容器的动态管理和监控[附完整源码下载]

    ​ (我是个封面) docker简介 Docker 是一个开源的应用容器引擎,和传统的虚拟机技术相比,Docker 容器性能开销极低,因此也广受开发者喜爱.随着基于docker的开发者越来越多,doc ...

  5. C# - VS2019 通过DataGridView实现对Oracle数据表的增删改查

    前言 通过VS2019建立WinFrm应用程序,搭建桌面程序后,通过封装数据库操作OracleHelper类和业务逻辑操作OracleSQL类,进而通过DataGridView实现对Oracle数据表 ...

  6. 实现对MySQL数据库进行分库/分表备份(shell脚本)

    工作中,往往数据库备份是件非常重要的事情,毕竟数据就是金钱,就是生命!废话不多,下面介绍一下:如何实现对MySQL数据库进行分库备份(shell脚本) Mysq数据库dump备份/还原语法: mysq ...

  7. 利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解

    本文转载自利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解 导语 由于最近工作需要利用 Jenkins 远程 API 操作 Jenkins 来完成一些列操作,就抽空研究 ...

  8. 在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试

    from:http://m.blog.csdn.net/article/details?id=51075023 在VS2015中先创建C#项目,然后再创建要编写的动态库DLL项目,这样做的好处是整个解 ...

  9. Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

    本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...

随机推荐

  1. java获取request中的参数、java解析URL问号后的参数

    java获取request中的参数.java解析URL问号后的参数.有时候我们需要从request中获取参数,或者获取拼接在Url后面的参数,有时候一个一个去拿有点麻烦,一起拿出来放在一个map里面需 ...

  2. PhoenixFD插件流体模拟——UI布局【Splash | Mist】详解

    液体飞溅 | 水雾 本文主要讲解Splash | Mist折叠栏中的内容.原文地址:https://docs.chaosgroup.com/display/PHX3MAX/Liquid+Splash+ ...

  3. pandas中的时间序列基础

    重要的数据形式时间序列 datetime以毫秒形式存储日期和时间 now = datetime.now() now datetime.datetime(2018, 12, 18, 14, 18, 27 ...

  4. Windows7下安装、部署Weblogic和发布war项目

    安装 1 从官方下载安装包 链接 2 下载之后,放到 Java8\jdk1.8.0\bin目录下 3 打开cmd,输入 java -jar . 4 5 6 下面是我自定义的目录, 7 8 9 10 1 ...

  5. Vue父子组件生命过程

    加载渲染过程 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount-& ...

  6. c#: .net framework 2.0支持扩展方法的办法

    c#之扩展方法是个好方法,可惜只在.net framework 3.5及以上版本中用. 2.0版本若用,其编译报错如下: 错误 无法定义新的扩展方法,因为找不到编译器所需的类型“System.Runt ...

  7. easyui 传递参数报错(错误:uncaught SyntaxError: Unexpected identifier)

    转自:https://www.cnblogs.com/javaboy2018/p/8733585.html 代码: 按钮事件: function formatOper(val, row, index) ...

  8. 手工脱壳之AsPack压缩脱壳-随机基址

    一.工具及壳介绍二.脱壳1.ESP定律脱壳2.单步跟踪脱壳3.基址重定位的修复 一.工具及壳介绍 使用工具:Ollydbg.PEID.ImportREC.LoadPE.010 Editor 查看待脱壳 ...

  9. Ubuntu16.04 静态IP设置

    为VMware虚拟机内安装的Ubuntu 16.04设置静态IP地址NAT方式 1.安装环境 VMware 12 Ubuntu 16.04 x86_64 2.在VMware中,配置网络环境 VMwar ...

  10. 1,fiddler的工作原理和安装

    1,工作原理就是通过设置代理监控客户端和服务端的协议 2,fiddler的安装 1,官方的下载地址:https://www.telerik.com/download/fiddler 一步步安装即可 2 ...