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包 这 ...
随机推荐
- Selenium Grid和IE /Firefox各种填坑
使用selenium grid的步骤 1.确保hub和node都安装并且配置好了java jdk. 2.在hub上运行以下命令. java -jar C:\Software\selenium\sele ...
- Earth Wind 一个查看全球风向的网站
可以查看整个地球的全貌 ,还能定位你的位置,特别是动画挺有意思 网址:https://earth.nullschool.net/#current/wind/surface/level/orthogra ...
- PostgreSQL 锁等待诊断详解
摘要PostgreSQL和大多数传统RDBMS一样,都设计了大量的锁来保证并发操作的数据一致性. 同时PG在设计锁等待时,以队列方式存储等待锁. 参考 ProcSleep()@src/backend/ ...
- 【Spring】SpringMVCの環境構築(簡)(Version3.1)
■Mavenでプロジェクトの新規 ■プロジェクトのイメージ ■必要なラブリア ■ソース ①pom.xml <?xml version="1.0" encoding=" ...
- Servlet第五篇(会话技术之Session)
Session 什么是Session Session 是另一种记录浏览器状态的机制.不同的是Cookie保存在浏览器中,Session保存在服务器中.用户使用浏览器访问服务器的时候,服务器把用户的信息 ...
- mysql权限操作(转)
慢慢看吧mysql中可以给你一个用户授予如select,insert,update,delete等其中的一个或者多个权限,主要使用grant命令,用法格式为: grant 权限 on 数据库对象 to ...
- 大数据下基于Tensorflow框架的深度学习示例教程
近几年,信息时代的快速发展产生了海量数据,诞生了无数前沿的大数据技术与应用.在当今大数据时代的产业界,商业决策日益基于数据的分析作出.当数据膨胀到一定规模时,基于机器学习对海量复杂数据的分析更能产生较 ...
- Populate screen data automatically
field zz_test-uname. module populate_record on chain-request. module populate_record input. ztlo_tes ...
- Spring+Quartz集群环境下定时调度的解决方案
集群环境可能出现的问题 在上一篇博客我们介绍了如何在自己的项目中从无到有的添加了Quartz定时调度引擎,其实就是一个Quartz 和Spring的整合过程,很容易实现,但是我们现在企业中项目通常都是 ...
- centos7+mariadb+防火墙,允许远程
centos7 已安装mariadb,想要允许数据库远程==数据库权限允许+系统允许 mariadb:允许数据库用户在所有ip使用某个用户远程 GRANT ALL PRIVILEGES ON *(数据 ...