c++实现对windwos 下socket 的封装(实现封包及拆包处理)
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 的封装(实现封包及拆包处理)的更多相关文章
- js 实现对ajax请求面向对象的封装
AJAX 是一种用于创建高速动态网页的技术.通过在后台与server进行少量数据交换.AJAX 能够使网页实现异步更新.这意味着能够在不又一次载入整个网页的情况下,对网页的某部分进行 ...
- 利用过滤器Filter和特性Attribute实现对Web API返回结果的封装和统一异常处理
在我们开发Web API应用的时候,我们可以借鉴ABP框架的过滤器Filter和特性Attribute的应用,实现对Web API返回结果的封装和统一异常处理,本篇随笔介绍利用AuthorizeAtt ...
- jmeter通过BeanShell 脚本,实现对http请求参数的加密
jmeter一直是一款很好的接口和性能测试工具,它是开源的,不需要为此支付任何费用,而且可以下载源码,可以在修改源代码并在此基础上拓展自己的功能或插件,它可以跟ant和jenkins结合起来搭建自己的 ...
- 基于spring-boot和docker-java实现对docker容器的动态管理和监控[附完整源码下载]
(我是个封面) docker简介 Docker 是一个开源的应用容器引擎,和传统的虚拟机技术相比,Docker 容器性能开销极低,因此也广受开发者喜爱.随着基于docker的开发者越来越多,doc ...
- C# - VS2019 通过DataGridView实现对Oracle数据表的增删改查
前言 通过VS2019建立WinFrm应用程序,搭建桌面程序后,通过封装数据库操作OracleHelper类和业务逻辑操作OracleSQL类,进而通过DataGridView实现对Oracle数据表 ...
- 实现对MySQL数据库进行分库/分表备份(shell脚本)
工作中,往往数据库备份是件非常重要的事情,毕竟数据就是金钱,就是生命!废话不多,下面介绍一下:如何实现对MySQL数据库进行分库备份(shell脚本) Mysq数据库dump备份/还原语法: mysq ...
- 利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解
本文转载自利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解 导语 由于最近工作需要利用 Jenkins 远程 API 操作 Jenkins 来完成一些列操作,就抽空研究 ...
- 在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试
from:http://m.blog.csdn.net/article/details?id=51075023 在VS2015中先创建C#项目,然后再创建要编写的动态库DLL项目,这样做的好处是整个解 ...
- Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问
本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...
随机推荐
- select 自匹配问题
原生js给select赋值或者vue绑定数据,会自匹配下拉选项的value或者key,从而显示对应的label或者对应的option的html eg: 原生: <select name=&quo ...
- Java框架spring 学习笔记(十六):c3p0连接池的配置以及dao使用jdbcTemplate
连接池可以大大提高数据库的性能和连接速度,将那些已连接的数据库连接存放在一个连接池里,以后别人要连接数据库的时候,将不会重新建立数据库连接,直接从连接池中取出可用的连接,用户使用完毕后,会释放连接重新 ...
- Java框架spring 学习笔记(十四):注解aop操作
回见Java框架spring Boot学习笔记(十三):aop实例操作,这里介绍注解aop操作 首先编写一个切入点HelloWorld.java package com.example.spring; ...
- 定点CORDIC算法求所有三角函数及向量模的原理分析、硬件实现(FPGA)
一.CORDIC算法 CORDIC(Coordinate Rotation DIgital Computer)是一种通过迭代对多种数学函数求值的方法,它可以对三角函数.双曲函数和平面旋转问题进行求解. ...
- 9. maps
C++有vertor,java有HashMap,C语言想使用则需要自行封装,不同的类型还需要再封装,特别麻烦. 看看Go语言的map的使用方法:var member map[string]int,创建 ...
- Jupyter Notebook 快捷键使用指南
因为使用Jupyter Notebook用鼠标选择菜单影响效率,遂将快捷命令记录于此 转自:http://blog.konghy.cn/2017/05/04/jupyter-notebook-hotk ...
- mysql链接服务器,update报错
select * from Openquery(MySQL, 'SELECT * FROM official.sys_hospital') 执行更新语句: ; 报错,错误信息: 链接服务器" ...
- 方位话机X2主、备用服务器问题
1.当主.备用服务器有关联时采用开启分组,SIP1.SIP2的方式 2.当主.备用服务器无关联时采用,SIP1主.备用服务器的方式
- java8--List转为Map、分组、过滤、求和等操作----代码示例
Java 8 函数式编程风格 Java 迄今为止最令人激动的特征.这些新的语言特征允许采用函数式风格来进行编码,我们可以用这些特性完成许多有趣的功能.这些特性如此有趣以至于被认为是不合理的.他们说会影 ...
- node 常用模块及方法fs,url,http,path
http://www.cnblogs.com/mangoxin/p/5664615.html https://www.liaoxuefeng.com/wiki/001434446689867b2715 ...