网络服务端和客户端添加普通发送模式

This commit is contained in:
~ Alone 2024-11-24 16:30:28 +08:00
parent c09ea42fa9
commit 60aa8883fa
9 changed files with 432 additions and 227 deletions

View File

@ -1,5 +1,6 @@
#include "SocketC.h"
//初始化socket
bool SocketC::initSocket()
{
//³õʼ»¯Ì×½Ó×Ö¿â
@ -23,11 +24,13 @@ bool SocketC::initSocket()
}
}
SocketC::SocketC(int bufSize, int modo)
//构造
SocketC::SocketC(int mode)
{
m_mode = mode;
}
//析构
SocketC::~SocketC()
{
if (state == 1)
@ -36,10 +39,11 @@ SocketC::~SocketC()
}
}
//连接到服务器
bool SocketC::Connect(string IP, UINT Prot)
{
if (!initSocket())
{
{//初始化失败
return false;
}
struct addrinfo* answer, hint;
@ -47,27 +51,25 @@ bool SocketC::Connect(string IP, UINT Prot)
ZeroMemory(&hint, sizeof(hint));
hint.ai_family = AF_INET;
hint.ai_socktype = SOCK_STREAM;
SOCKADDR_IN server_addr;
//解析域名如果传入的IP是域名的情况
if (getaddrinfo(IP.c_str(), NULL, &hint, &answer) == 0)
{
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = ((struct sockaddr_in*)(answer->ai_addr))->sin_addr.S_un.S_addr;
server_addr.sin_port = htons(Prot);
((SOCKADDR_IN*)&hint.ai_addr)->sin_port = htons(Prot);
//´´½¨Ì×½Ó×Ö
sclient = socket(AF_INET, SOCK_STREAM, 0);
//连接到服务器
if (connect(sclient, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
{//连接失败
WSACleanup();
return false;
}
else
{
{//连接成功创建线程接收数据
state = 1;
rec = std::thread((&SocketC::Receive), this);
return true;
@ -76,66 +78,85 @@ bool SocketC::Connect(string IP, UINT Prot)
return FALSE;
}
//接收数据函数
VOID SocketC::Receive()
{
char* buff = NULL;
while(state)
{
//开始接收数据
char buf[1024] = { 0 };
int len = recv(sclient, buf, 1024, 0);
int len = recv(sclient, buf, 1020, 0);
if (len ==SOCKET_ERROR || len == 0)
{
{//服务器关闭了
state = 0;
if (Cfunc != NULL)
{
Cfunc();
}
cout << "·þÎñÆ÷¶Ï¿ªÁ¬½Ó";
//cout << "服务器断开连接";
break;
}
int isStr;
buff = RecvBuff(buf, len, isStr);
while (buff)
{
if (m_mode == 0)
{//普通模式直接处理
if (Rfunc != NULL)
Rfunc(buf, len);
}
else if (m_mode == 1)
{//处理收到的数据避免出现粘包的情况
int isStr;
buff = RecvBuff(buf, len, isStr);
while (buff)
{
if (isStr == 1)
if (Rfunc != NULL)
{
AES aes;
string str = aes.DecryptionAES(buff, "qwertyuiopasdfgh");
Rfunc((char*)str.c_str(), str.length());
if (isStr == 1)
{//如果是字符串先解密
AES aes;
string str = aes.DecryptionAES(buff, "qwertyuiopasdfgh");
Rfunc((char*)str.c_str(), str.length());
}
else
Rfunc(buff, len);
}
else
Rfunc(buff, len);
delete buff;
len = 0;
buff = RecvBuff(NULL, len, isStr);
}
delete buff;
len = 0;
buff = RecvBuff(NULL, len, isStr);
}
}
return;
}
//处理收到的数据
char* SocketC::RecvBuff(char* buf, int& len, int& isStr)
{
char* buff = NULL;
MsgHead* h;
lock_guard<std::mutex> guard(msgLock);
//lock_guard<std::mutex> guard(msgLock);
//把收到的数据复制到缓冲区
if (len != 0)
memcpy_s(tmpBuf + bufLen, len, buf, len);
bufLen += len;
//判断缓冲区内的消息长度是否大于消息头
if (bufLen > sizeof(MsgHead))
{
{//检查消息头是由有问题
h = (MsgHead*)tmpBuf;
if (!CheckHead(h))
{//消息头不合规关闭连接
closesocket(sclient);
return NULL;
}
//判断当前消息是否收完
if (bufLen - sizeof(MsgHead) >= h->bufLen)
{
{//当前消息收完了
buff = new char[h->bufLen + 1];
ZeroMemory(buff, h->bufLen + 1);
memcpy_s(buff, h->bufLen, tmpBuf + sizeof(MsgHead), h->bufLen);
len = h->bufLen;
isStr = h->isStr;
bufLen = bufLen - len - sizeof(MsgHead);
//缓冲区数据前移
if (bufLen > 0)
memcpy_s(tmpBuf, bufLen, tmpBuf + sizeof(MsgHead) + len, bufLen);
}
@ -143,53 +164,104 @@ char* SocketC::RecvBuff(char* buf, int& len, int& isStr)
return buff;
}
int SocketC::SendData(const char* Date, int len, int isStr)
//检查消息头
BOOL SocketC::CheckHead(MsgHead* h)
{
MsgHead h;
h.isStr = isStr;
h.bufLen = len;
time(&h.tm);
string str = to_string(h.tm);
str += to_string(len);
md5 md;
str = md.StringToMD5(str);
memcpy_s(h.token, str.length(), str.c_str(), str.length());
char* buff = new char[sizeof(MsgHead) + len];
memcpy_s(buff, sizeof(MsgHead), &h, sizeof(MsgHead));
memcpy_s(buff + sizeof(MsgHead), len, Date, len);
int lenth = send(sclient, buff, len + sizeof(MsgHead), 0) - sizeof(MsgHead);
delete[] buff;
if (lenth < 0)
//消息长度不能大于10000
if (h->bufLen > 10000)
{
lenth = -1;
return FALSE;
}
return lenth;
//机密数据并验证发过来的Token是否正确
string str, str1;
str = to_string(h->tm);
str += to_string(h->bufLen);
md5 md;
str1 = md.StringToMD5(str);
str = h->token;
if (str == str1)
{//token正确验证发送消息的时间
time_t t1;
time(&t1);
if (abs(t1 - h->tm) < 300)
{
return TRUE;
}
}
return FALSE;
}
//发送数据包
int SocketC::SendData(const char* Data, int len, int isStr)
{
if (Data == NULL)
return -1;
if (m_mode == 0)
{//普通模式直接发送
return send(sclient, Data, len, 0);
}
else if (m_mode == 1)
{//生成token
MsgHead h;
h.isStr = isStr;
h.bufLen = len;
time(&h.tm);
string str = to_string(h.tm);
str += to_string(len);
md5 md;
str = md.StringToMD5(str);
memcpy_s(h.token, str.length(), str.c_str(), str.length());
char* buff = new char[sizeof(MsgHead) + len];
memcpy_s(buff, sizeof(MsgHead), &h, sizeof(MsgHead));
memcpy_s(buff + sizeof(MsgHead), len, Data, len);
//发送数据
int lenth = send(sclient, buff, len + sizeof(MsgHead), 0) - sizeof(MsgHead);
delete[] buff;
if (lenth < 0)
{
lenth = -1;
}
return lenth;
}
}
//发送字符串
BOOL SocketC::SendStr(string str)
{
if (str == "")
return FALSE;
AES aes;
string sendStr = aes.EncryptionAES(str, "qwertyuiopasdfgh");
if (-1 == SendData(sendStr.c_str(), sendStr.length(), 1))
{
return FALSE;
if (m_mode == 0)
{//普通模式直接发送
if (send(sclient, str.c_str(), str.length(), 0) == -1)
{
return FALSE;
}
}
else if (m_mode == 1)
{//加密发送的字符串并发送
AES aes;
string sendStr = aes.EncryptionAES(str, "qwertyuiopasdfgh");
if (-1 == SendData(sendStr.c_str(), sendStr.length(), 1))
{
return FALSE;
}
}
return TRUE;
}
//设置接收数据的回调函数
VOID SocketC::SetRecvFunc(function<VOID(char*, int)> fun)
{
Rfunc = fun;
}
//设置断开连接的回调函数
VOID SocketC::SetCloseFunc(function<VOID()> fun)
{
Cfunc = fun;
}
//断开连接
void SocketC::Close()
{
if (state != 0)

View File

@ -23,26 +23,26 @@ private:
char token[34] = { 0 };
};
char tmpBuf[10240] = { 0 };
int bufLen = 0;
SOCKET sclient = 0;
BOOL state = 0;
std::thread rec;
std::mutex msgLock;
function<VOID(char*, int)> Rfunc = NULL;
function<VOID()> Cfunc = NULL;
bool initSocket();
VOID Receive();
char* RecvBuff(char* buf, int& len, int& isStr);
char tmpBuf[10240] = { 0 }; //缓冲区
int bufLen = 0; //当前接收了多长的数据
SOCKET sclient = 0; //socket客户端
BOOL state = 0; //当前状态
int m_mode; //当前工作的模式
std::thread rec; //用来接数据的收线程
function<VOID(char*, int)> Rfunc = NULL; //接收到了数据的回调函数
function<VOID()> Cfunc = NULL; //断开连接的回调函数
bool initSocket(); //初始化socket
VOID Receive(); //接收数据函数
char* RecvBuff(char* buf, int& len, int& isStr); //处理收到的数据
BOOL CheckHead(MsgHead* h); //检查消息头
public:
SocketC(int bufSize = 4096, int modo = 0);
~SocketC();
bool Connect(string IP, UINT Prot);
int SendData(const char* Date, int len, int isStr = 0);
BOOL SendStr(string str);
VOID SetRecvFunc(function<VOID(char*, int)> fun);
VOID SetCloseFunc(function<VOID()> fun);
void Close();
SocketC(int mode = 0); //构造
~SocketC(); //析构
bool Connect(string IP, UINT Prot); //连接到服务器
int SendData(const char* Date, int len, int isStr = 0); //发送数据包
BOOL SendStr(string str); //发送字符串
VOID SetRecvFunc(function<VOID(char*, int)> fun); //设置接收数据的回调函数
VOID SetCloseFunc(function<VOID()> fun); //设置断开连接的回调函数
void Close(); //断开连接
};

View File

@ -6,7 +6,7 @@ using namespace std;
SocketC c;
SocketC c(1);
int flag = 1;
int myName = 0;

View File

@ -15,33 +15,45 @@ DWORD WINAPI SocketS::ThreadProc(LPVOID lpParameter)
while (server->g_flag)
{//获取完成端口的数据
BOOL bFlag = GetQueuedCompletionStatus(port, &len, &index, &lpOverlapped, INFINITE);
server->Lock.lock();
//server->Lock.lock();
clienInfo* clien = &server->ClienMap[index];
if (bFlag == TRUE && len > 0)
{// 接收到客户端消息
clien->Rbuflen += len;
DOSTART
if (clien->Rbuflen < sizeof(MsgHead))
break;
if (clien->Rbuflen - sizeof(MsgHead) < clien->h.bufLen)
break;
if (clien->buff == NULL)
break;
if (server->Rfunc == NULL)
break;
if (clien->h.isStr == 1)
{
AES aes;
string str = aes.DecryptionAES(clien->buff, "qwertyuiopasdfgh");
server->Rfunc(index, (char*)str.c_str(), str.length());
}
else
server->Rfunc(index, clien->buff, len);
ZeroMemory(clien->buff,sizeof(clien->buff));
clien->Rbuflen = 0;
DOEND
if (server->m_mode == 0)
{//普通模式
if (server->Rfunc != NULL)
{
server->Rfunc(index, clien->buff, len);
}
ZeroMemory(clien->buff, sizeof(clien->buff));
server->PostRecv(index); // 对自己投递接收
}
else if (server->m_mode == 1)
{
clien->Rbuflen += len;
DOSTART
if (clien->Rbuflen < sizeof(MsgHead))
break;
if (clien->Rbuflen - sizeof(MsgHead) < clien->h.bufLen)
break;
if (clien->buff == NULL)
break;
if (server->Rfunc == NULL)
break;
if (clien->h.isStr == 1)
{
AES aes;
string str = aes.DecryptionAES(clien->buff, "qwertyuiopasdfgh");
server->Rfunc(index, (char*)str.c_str(), str.length());
}
else
server->Rfunc(index, clien->buff, len);
ZeroMemory(clien->buff, sizeof(clien->buff));
clien->Rbuflen = 0;
DOEND
server->PostRecv(index); // 对自己投递接收
}
}
else
{//客户端关闭
@ -52,15 +64,22 @@ DWORD WINAPI SocketS::ThreadProc(LPVOID lpParameter)
server->CloseClien(index);
}
server->Lock.unlock();
//server->Lock.unlock();
}
server->Count--;
return 0;
}
SocketS::SocketS()
//构造
SocketS::SocketS(int mode)
{
m_mode = mode;
}
//析构
SocketS::~SocketS()
{
Close();
}
//投递消息
@ -68,28 +87,37 @@ VOID SocketS::PostRecv(int index)
{
WSABUF wsabuf;
clienInfo* clien = &ClienMap[index];
if (clien->Rbuflen < sizeof(MsgHead))
{//收到的消息还没消息头长
wsabuf.buf = (char*)&clien->h + clien->Rbuflen;
wsabuf.len = sizeof(MsgHead) - clien->Rbuflen;
}
else
if (m_mode == 0)
{
if (clien->Rbuflen == sizeof(MsgHead))
{//刚接收完消息头
if (!CheckHead(&clien->h))
{//消息头有问题
CloseClien(index);
return;
}
}
wsabuf.buf = clien->buff + (clien->Rbuflen - sizeof(MsgHead));
//剩余消息如果大于1020那么分块接收消息
if (clien->h.bufLen - clien->Rbuflen + sizeof(MsgHead) > 1020)
wsabuf.len = 1020;
else
wsabuf.len = clien->h.bufLen - clien->Rbuflen + sizeof(MsgHead);
wsabuf.buf = clien->buff;
wsabuf.len = 1020;
}
else if (m_mode == 1)
{
if (clien->Rbuflen < sizeof(MsgHead))
{//收到的消息还没消息头长
wsabuf.buf = (char*)&clien->h + clien->Rbuflen;
wsabuf.len = sizeof(MsgHead) - clien->Rbuflen;
}
else
{
if (clien->Rbuflen == sizeof(MsgHead))
{//刚接收完消息头
if (!CheckHead(&clien->h))
{//消息头有问题
CloseClien(index);
return;
}
}
wsabuf.buf = clien->buff + (clien->Rbuflen - sizeof(MsgHead));
//剩余消息如果大于1020那么分块接收消息
if (clien->h.bufLen - clien->Rbuflen + sizeof(MsgHead) > 1020)
wsabuf.len = 1020;
else
wsabuf.len = clien->h.bufLen - clien->Rbuflen + sizeof(MsgHead);
}
}
//让完成端口继续接收数据
DWORD dwRecvCount = wsabuf.len;
DWORD dwFlag = 0;
@ -217,6 +245,8 @@ BOOL SocketS::Creat(int Prot)
//关闭服务端
void SocketS::Close()
{//清除客户端
if (g_flag == 0)
return;
g_flag = 0;
Lock.lock();
for (auto i = ClienMap.begin(); i != ClienMap.end(); i++)
@ -269,29 +299,40 @@ VOID SocketS::GetClienName(int index, string& IP, int& Prot)
//发送数据包
int SocketS::SendData(int index,const char* buf, int len, int isStr)
{//创建消息头生成token
MsgHead h;
h.bufLen = len;
h.isStr = isStr;
time(&h.tm);
string str = to_string(h.tm);
str += to_string(len);
md5 md;
str = md.StringToMD5(str);
memcpy_s(h.token, str.length(), str.c_str(), str.length());
//合并消息头和消息体
char* buff = new char[sizeof(MsgHead) + len];
memcpy_s(buff, sizeof(MsgHead), &h, sizeof(MsgHead));
memcpy_s(buff + sizeof(MsgHead), len, buf, len);
//发送消息
int lenth = PostSend(index, buff, len + sizeof(MsgHead)) - sizeof(MsgHead);
delete[] buff;
if (lenth < 0)
{//消息发送失败
CloseClien(index);
lenth = -1;
{
if (buf == NULL)
return -1;
if (m_mode == 0)
{//普通模式
return PostSend(index, buf, len);
}
return lenth;
else if (m_mode == 1)
{
//创建消息头生成token
MsgHead h;
h.bufLen = len;
h.isStr = isStr;
time(&h.tm);
string str = to_string(h.tm);
str += to_string(len);
md5 md;
str = md.StringToMD5(str);
memcpy_s(h.token, str.length(), str.c_str(), str.length());
//合并消息头和消息体
char* buff = new char[sizeof(MsgHead) + len];
memcpy_s(buff, sizeof(MsgHead), &h, sizeof(MsgHead));
memcpy_s(buff + sizeof(MsgHead), len, buf, len);
//发送消息
int lenth = PostSend(index, buff, len + sizeof(MsgHead)) - sizeof(MsgHead);
delete[] buff;
if (lenth < 0)
{//消息发送失败
CloseClien(index);
lenth = -1;
}
return lenth;
}
return -1;
}
//发送字符串
@ -299,13 +340,23 @@ BOOL SocketS::SendStr(int index, string str)
{//判断消息不能为空
if (str == "")
return FALSE;
//加密字符串
AES aes;
string sendStr = aes.EncryptionAES(str,"qwertyuiopasdfgh");
//发送消息
if (-1 == SendData(index, sendStr.c_str(), sendStr.length(), 1))
{//消息发送失败
return FALSE;
if (m_mode == 0)
{//普通模式
if (PostSend(index, str.c_str(), str.length()) == -1)
{
return FALSE;
}
}
else if (m_mode == 1)
{
//加密字符串
AES aes;
string sendStr = aes.EncryptionAES(str, "qwertyuiopasdfgh");
//发送消息
if (-1 == SendData(index, sendStr.c_str(), sendStr.length(), 1))
{//消息发送失败
return FALSE;
}
}
return TRUE;
}

View File

@ -45,6 +45,7 @@ private:
std::thread *ListenClien; //监听线程
int Count = 0; //工作者线程多少个
mutex Lock; //线程锁
int m_mode; //当前工作的模式
function<VOID(int,char*,int)> Rfunc = NULL; //接收数据的回调函数
function<VOID(int)> Cfunc = NULL; //客户端关闭的回调函数
@ -55,7 +56,8 @@ private:
VOID Listens(); //监听消息函数
public:
SocketS(); //¹¹Ôì
SocketS(int mode = 0); //构造
~SocketS(); //构造
BOOL Creat(int Prot); //创建服务端
void Close(); //关闭服务端
VOID SetRecvFunc(function<VOID(int, char*, int)> fun); //设置接收消息的回调函数

View File

@ -29,7 +29,7 @@ struct msgInfo
std::map<int/*name*/, int/*index*/> clienMap;
std::map<int/*index*/, int/*name*/> clienIndex;
SocketS s;
SocketS s(1);
int cont = 0;
VOID closeFunc(int index)
{
@ -52,8 +52,8 @@ VOID recvFunc(int index, char* buf, int len)
int main(void)
{
//s.SetRecvFunc([&tt](SocketS::msgInfo info) {return tt.ppp(info); });
s.Creat(6666);
s.Close();
//s.Creat(6666);
//s.Close();
s.SetCloseFunc(closeFunc);
s.SetRecvFunc(recvFunc);

View File

@ -1,5 +1,6 @@
#include "SocketC.h"
//初始化socket
bool SocketC::initSocket()
{
//初始化套接字库
@ -23,11 +24,13 @@ bool SocketC::initSocket()
}
}
SocketC::SocketC(int bufSize, int modo)
//构造
SocketC::SocketC(int mode)
{
m_mode = mode;
}
//析构
SocketC::~SocketC()
{
if (state == 1)
@ -36,10 +39,11 @@ SocketC::~SocketC()
}
}
//连接到服务器
bool SocketC::Connect(string IP, UINT Prot)
{
if (!initSocket())
{
{//初始化失败
return false;
}
struct addrinfo* answer, hint;
@ -47,27 +51,25 @@ bool SocketC::Connect(string IP, UINT Prot)
ZeroMemory(&hint, sizeof(hint));
hint.ai_family = AF_INET;
hint.ai_socktype = SOCK_STREAM;
SOCKADDR_IN server_addr;
//解析域名如果传入的IP是域名的情况
if (getaddrinfo(IP.c_str(), NULL, &hint, &answer) == 0)
{
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = ((struct sockaddr_in*)(answer->ai_addr))->sin_addr.S_un.S_addr;
server_addr.sin_port = htons(Prot);
((SOCKADDR_IN*)&hint.ai_addr)->sin_port = htons(Prot);
//创建套接字
sclient = socket(AF_INET, SOCK_STREAM, 0);
//连接到服务器
if (connect(sclient, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
{//连接失败
WSACleanup();
return false;
}
else
{
{//连接成功创建线程接收数据
state = 1;
rec = std::thread((&SocketC::Receive), this);
return true;
@ -76,15 +78,17 @@ bool SocketC::Connect(string IP, UINT Prot)
return FALSE;
}
//接收数据函数
VOID SocketC::Receive()
{
char* buff = NULL;
while(state)
{
//开始接收数据
char buf[1024] = { 0 };
int len = recv(sclient, buf, 1024, 0);
int len = recv(sclient, buf, 1020, 0);
if (len ==SOCKET_ERROR || len == 0)
{
{//服务器关闭了
state = 0;
if (Cfunc != NULL)
{
@ -93,49 +97,66 @@ VOID SocketC::Receive()
//cout << "服务器断开连接";
break;
}
int isStr;
buff = RecvBuff(buf, len, isStr);
while (buff)
{
if (m_mode == 0)
{//普通模式直接处理
if (Rfunc != NULL)
Rfunc(buf, len);
}
else if (m_mode == 1)
{//处理收到的数据避免出现粘包的情况
int isStr;
buff = RecvBuff(buf, len, isStr);
while (buff)
{
if (isStr == 1)
if (Rfunc != NULL)
{
AES aes;
string str = aes.DecryptionAES(buff, "qwertyuiopasdfgh");
Rfunc((char*)str.c_str(), str.length());
if (isStr == 1)
{//如果是字符串先解密
AES aes;
string str = aes.DecryptionAES(buff, "qwertyuiopasdfgh");
Rfunc((char*)str.c_str(), str.length());
}
else
Rfunc(buff, len);
}
else
Rfunc(buff, len);
delete buff;
len = 0;
buff = RecvBuff(NULL, len, isStr);
}
delete buff;
len = 0;
buff = RecvBuff(NULL, len, isStr);
}
}
return;
}
//处理收到的数据
char* SocketC::RecvBuff(char* buf, int& len, int& isStr)
{
char* buff = NULL;
MsgHead* h;
lock_guard<std::mutex> guard(msgLock);
//lock_guard<std::mutex> guard(msgLock);
//把收到的数据复制到缓冲区
if (len != 0)
memcpy_s(tmpBuf + bufLen, len, buf, len);
bufLen += len;
//判断缓冲区内的消息长度是否大于消息头
if (bufLen > sizeof(MsgHead))
{
{//检查消息头是由有问题
h = (MsgHead*)tmpBuf;
if (!CheckHead(h))
{//消息头不合规关闭连接
closesocket(sclient);
return NULL;
}
//判断当前消息是否收完
if (bufLen - sizeof(MsgHead) >= h->bufLen)
{
{//当前消息收完了
buff = new char[h->bufLen + 1];
ZeroMemory(buff, h->bufLen + 1);
memcpy_s(buff, h->bufLen, tmpBuf + sizeof(MsgHead), h->bufLen);
len = h->bufLen;
isStr = h->isStr;
bufLen = bufLen - len - sizeof(MsgHead);
//缓冲区数据前移
if (bufLen > 0)
memcpy_s(tmpBuf, bufLen, tmpBuf + sizeof(MsgHead) + len, bufLen);
}
@ -143,53 +164,104 @@ char* SocketC::RecvBuff(char* buf, int& len, int& isStr)
return buff;
}
int SocketC::SendData(const char* Date, int len, int isStr)
//检查消息头
BOOL SocketC::CheckHead(MsgHead* h)
{
MsgHead h;
h.isStr = isStr;
h.bufLen = len;
time(&h.tm);
string str = to_string(h.tm);
str += to_string(len);
md5 md;
str = md.StringToMD5(str);
memcpy_s(h.token, str.length(), str.c_str(), str.length());
char* buff = new char[sizeof(MsgHead) + len];
memcpy_s(buff, sizeof(MsgHead), &h, sizeof(MsgHead));
memcpy_s(buff + sizeof(MsgHead), len, Date, len);
int lenth = send(sclient, buff, len + sizeof(MsgHead), 0) - sizeof(MsgHead);
delete[] buff;
if (lenth < 0)
//消息长度不能大于10000
if (h->bufLen > 10000)
{
lenth = -1;
return FALSE;
}
return lenth;
//机密数据并验证发过来的Token是否正确
string str, str1;
str = to_string(h->tm);
str += to_string(h->bufLen);
md5 md;
str1 = md.StringToMD5(str);
str = h->token;
if (str == str1)
{//token正确验证发送消息的时间
time_t t1;
time(&t1);
if (abs(t1 - h->tm) < 300)
{
return TRUE;
}
}
return FALSE;
}
//发送数据包
int SocketC::SendData(const char* Data, int len, int isStr)
{
if (Data == NULL)
return -1;
if (m_mode == 0)
{//普通模式直接发送
return send(sclient, Data, len, 0);
}
else if (m_mode == 1)
{//生成token
MsgHead h;
h.isStr = isStr;
h.bufLen = len;
time(&h.tm);
string str = to_string(h.tm);
str += to_string(len);
md5 md;
str = md.StringToMD5(str);
memcpy_s(h.token, str.length(), str.c_str(), str.length());
char* buff = new char[sizeof(MsgHead) + len];
memcpy_s(buff, sizeof(MsgHead), &h, sizeof(MsgHead));
memcpy_s(buff + sizeof(MsgHead), len, Data, len);
//发送数据
int lenth = send(sclient, buff, len + sizeof(MsgHead), 0) - sizeof(MsgHead);
delete[] buff;
if (lenth < 0)
{
lenth = -1;
}
return lenth;
}
}
//发送字符串
BOOL SocketC::SendStr(string str)
{
if (str == "")
return FALSE;
AES aes;
string sendStr = aes.EncryptionAES(str, "qwertyuiopasdfgh");
if (-1 == SendData(sendStr.c_str(), sendStr.length(), 1))
{
return FALSE;
if (m_mode == 0)
{//普通模式直接发送
if (send(sclient, str.c_str(), str.length(), 0) == -1)
{
return FALSE;
}
}
else if (m_mode == 1)
{//加密发送的字符串并发送
AES aes;
string sendStr = aes.EncryptionAES(str, "qwertyuiopasdfgh");
if (-1 == SendData(sendStr.c_str(), sendStr.length(), 1))
{
return FALSE;
}
}
return TRUE;
}
//设置接收数据的回调函数
VOID SocketC::SetRecvFunc(function<VOID(char*, int)> fun)
{
Rfunc = fun;
}
//设置断开连接的回调函数
VOID SocketC::SetCloseFunc(function<VOID()> fun)
{
Cfunc = fun;
}
//断开连接
void SocketC::Close()
{
if (state != 0)

View File

@ -1,8 +1,16 @@
#pragma once
#include "pub.h"
#include<iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <thread>
#include <mutex>
#include <functional>
#include "md5.h"
#include "AES.h"
#pragma comment(lib,"ws2_32.lib")
using namespace std;
class SocketC
{
private:
@ -15,26 +23,26 @@ private:
char token[34] = { 0 };
};
char tmpBuf[10240] = { 0 };
int bufLen = 0;
SOCKET sclient = 0;
BOOL state = 0;
std::thread rec;
std::mutex msgLock;
function<VOID(char*, int)> Rfunc = NULL;
function<VOID()> Cfunc = NULL;
bool initSocket();
VOID Receive();
char* RecvBuff(char* buf, int& len, int& isStr);
char tmpBuf[10240] = { 0 }; //缓冲区
int bufLen = 0; //当前接收了多长的数据
SOCKET sclient = 0; //socket客户端
BOOL state = 0; //当前状态
int m_mode; //当前工作的模式
std::thread rec; //用来接数据的收线程
function<VOID(char*, int)> Rfunc = NULL; //接收到了数据的回调函数
function<VOID()> Cfunc = NULL; //断开连接的回调函数
bool initSocket(); //初始化socket
VOID Receive(); //接收数据函数
char* RecvBuff(char* buf, int& len, int& isStr); //处理收到的数据
BOOL CheckHead(MsgHead* h); //检查消息头
public:
SocketC(int bufSize = 4096, int modo = 0);
~SocketC();
bool Connect(string IP, UINT Prot);
int SendData(const char* Date, int len, int isStr = 0);
BOOL SendStr(string str);
VOID SetRecvFunc(function<VOID(char*, int)> fun);
VOID SetCloseFunc(function<VOID()> fun);
void Close();
SocketC(int mode = 0); //构造
~SocketC(); //析构
bool Connect(string IP, UINT Prot); //连接到服务器
int SendData(const char* Date, int len, int isStr = 0); //发送数据包
BOOL SendStr(string str); //发送字符串
VOID SetRecvFunc(function<VOID(char*, int)> fun); //设置接收数据的回调函数
VOID SetCloseFunc(function<VOID()> fun); //设置断开连接的回调函数
void Close(); //断开连接
};

View File

@ -3,7 +3,7 @@
#include "Json.h"
#include "SocketC.h"
SocketC tcpc;
SocketC tcpc(1);
char* U8ToUnicode(char* szU8)
{