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包 这 ...
随机推荐
- Win10系统总是提示"在商店中查找应用"的关闭方法
Win10系统总是提示"在商店中查找应用"该怎么关闭?win10中打开文件的时候总是提示在商店中查找应用,但是自己的电脑中有程序可以打开这个文件,不需要去商店中下载,该怎么取消这个 ...
- day44 mysql高级部分内容
复习 1.多表查询 2.navicat 3.pymysql 1.视图 ***(是一个虚拟表,非真实存在的) 引子 select * from emp left join dep on emp.dep_ ...
- MySQL如何解决1209错误
1209 - The MySQL server is running with the--read-only option so it cannot execute this sta ...
- 启动tomcat时报错:http-nio-8080-exec-10
启动Tomcat后访问 http://192.168.199.10:8080/jpress-web-newest 网页,查看日志有报错 问题原因:Java的内存溢出 故障现象为: cat /app ...
- linux命令——wc
wc 统计文件里面有多少单词,多少行,多少字符. wc语法 [root@www ~]# wc [-lwm] 选项与参数: -l :仅列出行: -w :仅列出多少字(英文单字): -m :多少字符: 默 ...
- 重启虚拟机后dhclient进程未运行解决办法
问题分析 重启虚拟机后,dhclient进程未运行的根因通常为: 1.NetworkManager未开启自启动导致的dhclient进程未运行 2.网卡设置未纳入NetworkManager管理导致的 ...
- Redux 检测状态树变更
一 概述 Redux只是检测引用是否改变. 如果状态树的某个值是对象.数组等,在reducer中需要生成一个新对象.新数组,才能被Redux检测到变更. let fruits = ['apple',' ...
- [剑指Offer]29-顺时针打印矩阵-Java
题目链接 https://www.nowcoder.com/practice/9b4c81a02cd34f76be2659fa0d54342a?tpId=13&tqId=11172&t ...
- Struts2源码解析-----转载
前面一节描述的Struts2很多东西,这节是对源码进行分析描述,通过这一节应该对struts2有了清楚认识! 还是把Struts2这个框图贴出来: 第一步:HttpServletRequest进入到S ...
- 安卓学习 Drawable对象
whie(!images[currentImage].endWith(".PNG")&&!images[currentImage].endWith(".p ...