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. Win10系统总是提示"在商店中查找应用"的关闭方法

    Win10系统总是提示"在商店中查找应用"该怎么关闭?win10中打开文件的时候总是提示在商店中查找应用,但是自己的电脑中有程序可以打开这个文件,不需要去商店中下载,该怎么取消这个 ...

  2. 安装setuptools 报错缺少zlib

    # yum install zlib # yum install zlib-devel 下载成功后,进入python2.7的目录,重新执行 #make #make install 此时先前执行的 软连 ...

  3. Linux - 其他命令

    其他命令 目标 查找文件 find 软链接 ln 打包和压缩 tar 软件安装 apt-get 01. 查找文件 find 命令功能非常强大,通常用来在 特定的目录下 搜索 符合条件的文件 序号 命令 ...

  4. vim 常用指令总结

    vim的好处(四大好处) vim具有大量的操作技巧,编辑能力强大且速度比其他工具快的多! (这里举个简单的小例子:将每行的前四个字母复制到每行的末尾; 将文本中的所有word替换为words; 等等很 ...

  5. jquery 中dataTable显示加载中,图片或文字

    引入js文件 <script type="text/javascript" src="${basePath}/lib/datatables/1.10.0/jquer ...

  6. mycat使用之MySQL单库分表及均分数据

    转载自 https://blog.csdn.net/smilefyx/article/details/72810531 1.首先在Mycat官网下载安装包,这里就以最新的1.6版本为例,下载地址为:  ...

  7. js真乃神器也

    var a =document.getElementsByClassName('SearchResult__title-text'); for (i = 0;i < a.length;i++){ ...

  8. 在MyEclipse中使用spring-boot+mybatis+freemarker实现基本的增删改查

    一.基本环境 二.创建实体类 1.User.java package bjredcross.rainbowplans.model; import bjredcross.rainbowplans.com ...

  9. python基础之Day17

    一.包 1.包 含有--init--.py的文件夹  是模块的一种形式 本质是一个文件夹(用来存放文件,包内所有的文件都是用来被导入的) import 包 包.名字     往包的init里加名字 导 ...

  10. Python json.dumps 自定义序列化操作

    def login_ajax(request): if request.method == "GET": return render(request, 'login_ajax.ht ...