优化网络服务端和客户端
This commit is contained in:
parent
9e6c36bd4b
commit
f53586dad5
@ -73,46 +73,101 @@ bool SocketC::Connect(string IP, UINT Prot)
|
|||||||
|
|
||||||
VOID SocketC::Receive()
|
VOID SocketC::Receive()
|
||||||
{
|
{
|
||||||
|
char* buff = NULL;
|
||||||
while(state)
|
while(state)
|
||||||
{
|
{
|
||||||
MsgInfo* info = new MsgInfo;
|
char buf[2048] = { 0 };
|
||||||
info->len = recv(sclient, info->buff, 2047, 0);
|
int len = recv(sclient, buf, 2048, 0);
|
||||||
msgLock.lock();
|
if (len ==SOCKET_ERROR || len == 0)
|
||||||
msgList.push_back(info);
|
{
|
||||||
msgLock.unlock();
|
state = 0;
|
||||||
|
if (Cfunc != NULL)
|
||||||
|
{
|
||||||
|
Cfunc();
|
||||||
|
}
|
||||||
|
cout << "服务器断开连接";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buff = RecvBuff(buf, len);
|
||||||
|
while (buff)
|
||||||
|
{
|
||||||
|
if (Rfunc != NULL)
|
||||||
|
{
|
||||||
|
Rfunc(buff, len);
|
||||||
|
}
|
||||||
|
delete buff;
|
||||||
|
len = 0;
|
||||||
|
buff = RecvBuff(NULL, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SocketC::Send(const char* Date, int len)
|
char* SocketC::RecvBuff(char* buf, int& len)
|
||||||
{
|
{
|
||||||
return send(sclient, Date, len, 0);
|
char* buff = NULL;
|
||||||
|
MsgHead* h;
|
||||||
|
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 (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;
|
||||||
|
bufLen = bufLen - len - sizeof(MsgHead);
|
||||||
|
if (bufLen > 0)
|
||||||
|
memcpy_s(tmpBuf, bufLen, tmpBuf + sizeof(MsgHead) + len, bufLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketC::MsgInfo* SocketC::GetMsg()
|
|
||||||
|
int SocketC::Send(const char* Date, int len)
|
||||||
{
|
{
|
||||||
MsgInfo* info = NULL;
|
MsgHead h;
|
||||||
msgLock.lock();
|
h.bufLen = len;
|
||||||
if (msgList.size() > 0)
|
time(&h.tm);
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
info = *msgList.begin();
|
lenth = -1;
|
||||||
msgList.pop_front();
|
|
||||||
}
|
}
|
||||||
msgLock.unlock();
|
return lenth;
|
||||||
return info;
|
}
|
||||||
|
|
||||||
|
VOID SocketC::SetRecvFunc(function<VOID(char*, int)> fun)
|
||||||
|
{
|
||||||
|
Rfunc = fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SocketC::SetCloseFunc(function<VOID()> fun)
|
||||||
|
{
|
||||||
|
Cfunc = fun;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketC::Close()
|
void SocketC::Close()
|
||||||
{
|
{
|
||||||
state = 0;
|
if (state != 0)
|
||||||
//¹Ø±ÕÌ×½Ó×Ö
|
{
|
||||||
closesocket(sclient);
|
state = 0;
|
||||||
//ÊÍ·ÅDLL×ÊÔ´
|
//关闭套接字
|
||||||
|
shutdown(sclient, SD_BOTH);
|
||||||
|
closesocket(sclient);
|
||||||
|
//释放DLL资源
|
||||||
|
rec.join();
|
||||||
|
}
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
//for (size_t i = 0; i < msgList.size(); i++)
|
|
||||||
//{
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
msgList.clear();
|
|
||||||
rec.join();
|
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <map>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <list>
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
#pragma comment(lib,"ws2_32.lib")
|
#pragma comment(lib,"ws2_32.lib")
|
||||||
@ -13,24 +12,34 @@ using namespace std;
|
|||||||
|
|
||||||
class SocketC
|
class SocketC
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
struct MsgInfo
|
|
||||||
{
|
|
||||||
int len = 0; //ÄÚÈݳ¤¶È
|
|
||||||
char buff[2048] = {0}; //ÏûÏ¢ÄÚÈÝ
|
|
||||||
};
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
struct MsgHead
|
||||||
|
{
|
||||||
|
int MyIndex = 0;
|
||||||
|
int bufLen = 0;
|
||||||
|
time_t tm = 0;
|
||||||
|
char token[34] = { 0 };
|
||||||
|
};
|
||||||
|
char tmpBuf[10240] = { 0 };
|
||||||
|
int bufLen = 0;
|
||||||
SOCKET sclient = 0;
|
SOCKET sclient = 0;
|
||||||
std::list<MsgInfo*>msgList;
|
|
||||||
BOOL state = 0;
|
BOOL state = 0;
|
||||||
std::thread rec;
|
std::thread rec;
|
||||||
std::mutex msgLock;
|
std::mutex msgLock;
|
||||||
|
function<VOID(char*, int)> Rfunc = NULL;
|
||||||
|
function<VOID()> Cfunc = NULL;
|
||||||
bool initSocket();
|
bool initSocket();
|
||||||
VOID Receive();
|
VOID Receive();
|
||||||
|
char* RecvBuff(char* buf, int& len);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~SocketC();
|
~SocketC();
|
||||||
bool Connect(string IP, UINT Prot);
|
bool Connect(string IP, UINT Prot);
|
||||||
int Send(const char* Date, int len);
|
int Send(const char* Date, int len);
|
||||||
MsgInfo* GetMsg();
|
|
||||||
|
VOID SetRecvFunc(function<VOID(char*, int)> fun);
|
||||||
|
VOID SetCloseFunc(function<VOID()> fun);
|
||||||
void Close();
|
void Close();
|
||||||
};
|
};
|
||||||
|
135
网络客户端/网络客户端.cpp
135
网络客户端/网络客户端.cpp
@ -1,135 +1,42 @@
|
|||||||
#include<iostream>
|
#include<iostream>
|
||||||
#include "SocketC.h"
|
#include "SocketC.h"
|
||||||
|
#include <string>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct clienMsg
|
|
||||||
{
|
|
||||||
int myName;
|
|
||||||
int snedName;
|
|
||||||
int code;
|
|
||||||
int len;
|
|
||||||
char buf[1024];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SocketC c;
|
SocketC c;
|
||||||
int flag = 1;
|
int flag = 1;
|
||||||
int myName = 0;
|
int myName = 0;
|
||||||
|
|
||||||
VOID LogIn() {
|
void recvFunc(char* buf, int len)
|
||||||
if (myName != 0)
|
|
||||||
{
|
|
||||||
cout << "当前已登录无需重复登录,当前账号:"<<myName<<"\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int name;
|
|
||||||
char pass[16] = { 0 };
|
|
||||||
cout << "请输入账号:";
|
|
||||||
cin >> name;
|
|
||||||
cout << "请输入密码:";
|
|
||||||
cin >> pass;
|
|
||||||
clienMsg msg;
|
|
||||||
msg.myName = name;
|
|
||||||
msg.code = 1;
|
|
||||||
msg.snedName = 0;
|
|
||||||
memcpy_s(msg.buf, 16, pass, 16);
|
|
||||||
c.Send((char*)&msg, sizeof(clienMsg));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID SendMsg()
|
|
||||||
{
|
{
|
||||||
if (myName == 0)
|
cout << buf << "\n";
|
||||||
{
|
}
|
||||||
cout << "请先登录账号\n";
|
void closeFunc()
|
||||||
return;
|
{
|
||||||
}
|
cout << "服务器断开连接";
|
||||||
int name;
|
|
||||||
char buf[1000] = { 0 };
|
|
||||||
cout << "你要给那个账号发消息\n";
|
|
||||||
cin >> name;
|
|
||||||
cout << "请输入要发送的内容:";
|
|
||||||
cin >> buf;
|
|
||||||
clienMsg msg;
|
|
||||||
msg.myName = myName;
|
|
||||||
msg.snedName = name;
|
|
||||||
msg.code = 2;
|
|
||||||
memcpy_s(msg.buf, 1000, buf, 1000);
|
|
||||||
c.Send((char*)&msg, sizeof(clienMsg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
c.SetRecvFunc(recvFunc);
|
||||||
|
c.SetCloseFunc(closeFunc);
|
||||||
c.Connect("127.0.0.1", 6666);
|
c.Connect("127.0.0.1", 6666);
|
||||||
|
string str;
|
||||||
thread th([] {
|
for (int i = 0; i < 10000000; i++)
|
||||||
while (flag)
|
|
||||||
{
|
|
||||||
SocketC::MsgInfo* info;
|
|
||||||
clienMsg* msg;
|
|
||||||
info = c.GetMsg();
|
|
||||||
if (info)
|
|
||||||
{
|
|
||||||
msg = (clienMsg*)info->buff;
|
|
||||||
|
|
||||||
std::string buf;
|
|
||||||
|
|
||||||
buf = msg->buf;
|
|
||||||
switch (msg->code)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
cout << buf << "\n";
|
|
||||||
if (buf == "登录成功")
|
|
||||||
{
|
|
||||||
myName = msg->myName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
myName = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (msg->len != -1)
|
|
||||||
cout << msg->myName << "对你说:";
|
|
||||||
cout << buf << "\n";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
delete info;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Sleep(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
cout << "输入1登录账号\n";
|
|
||||||
cout << "输入2给他人发消息\n";
|
|
||||||
cout << "输入其他退出系统\n";
|
|
||||||
int code = 0;
|
|
||||||
while (1)
|
|
||||||
{
|
{
|
||||||
cin >> code;
|
str = to_string(i);
|
||||||
switch (code)
|
c.Send(str.c_str(), str.length());
|
||||||
|
if (i % 100 == 0)
|
||||||
{
|
{
|
||||||
case 1:
|
Sleep(100);
|
||||||
LogIn();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
SendMsg();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
flag = 0;
|
|
||||||
th.join();
|
|
||||||
c.Close();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Sleep(10);
|
||||||
|
c.Close();
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
}
|
}
|
@ -13,23 +13,26 @@ DWORD WINAPI SocketS::ThreadProc(LPVOID lpParameter)
|
|||||||
while (server->g_flag)
|
while (server->g_flag)
|
||||||
{
|
{
|
||||||
BOOL bFlag = GetQueuedCompletionStatus(port, &NumberOfBytes, &index, &lpOverlapped, INFINITE);
|
BOOL bFlag = GetQueuedCompletionStatus(port, &NumberOfBytes, &index, &lpOverlapped, INFINITE);
|
||||||
|
clienInfo* clien = &server->ClienMap[index];
|
||||||
|
|
||||||
if (FALSE == bFlag)
|
if (FALSE == bFlag)
|
||||||
{
|
{
|
||||||
if (64 == GetLastError())
|
if (64 == GetLastError())
|
||||||
{
|
{
|
||||||
printf("客户端异常下线\n");
|
printf("客户端异常下线\n");
|
||||||
msgInfo* info = new msgInfo;
|
clien->c_Sock = 0;
|
||||||
info->index = index;
|
clien->c_Olp.hEvent = NULL;
|
||||||
info->len = -1;
|
server->ClienMap.erase(index);
|
||||||
server->msgLock.lock();
|
if (server->Cfunc != NULL)
|
||||||
server->msgList.push_back(info);
|
{
|
||||||
server->msgLock.unlock();
|
server->Cfunc(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分类处理
|
// 分类处理
|
||||||
|
//lock_guard<std::mutex> guard(clien->msgLock);
|
||||||
if (0 == index) // accept
|
if (0 == index) // accept
|
||||||
{
|
{
|
||||||
printf("accept\n");
|
printf("accept\n");
|
||||||
@ -39,6 +42,7 @@ DWORD WINAPI SocketS::ThreadProc(LPVOID lpParameter)
|
|||||||
{
|
{
|
||||||
printf("CreateIoCompletionPort 绑定失败 error:%d\n", GetLastError());
|
printf("CreateIoCompletionPort 绑定失败 error:%d\n", GetLastError());
|
||||||
closesocket(server->ClienMap[server->g_count].c_Sock);
|
closesocket(server->ClienMap[server->g_count].c_Sock);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
server->PostRecv(server->g_count); // 投递recv
|
server->PostRecv(server->g_count); // 投递recv
|
||||||
@ -51,39 +55,41 @@ DWORD WINAPI SocketS::ThreadProc(LPVOID lpParameter)
|
|||||||
{
|
{
|
||||||
printf("客户端正常下线\n");
|
printf("客户端正常下线\n");
|
||||||
|
|
||||||
closesocket(server->ClienMap[index].c_Sock);
|
closesocket(clien->c_Sock);
|
||||||
WSACloseEvent(server->ClienMap[index].c_Olp.hEvent);
|
WSACloseEvent(clien->c_Olp.hEvent);
|
||||||
// 从数组中删掉
|
// 从数组中删掉
|
||||||
server->ClienMap[index].c_Sock = 0;
|
clien->c_Sock = 0;
|
||||||
server->ClienMap[index].c_Olp.hEvent = NULL;
|
clien->c_Olp.hEvent = NULL;
|
||||||
server->ClienMap.erase(index);
|
server->ClienMap.erase(index);
|
||||||
|
if (server->Cfunc != NULL)
|
||||||
msgInfo* info = new msgInfo;
|
{
|
||||||
info->index = index;
|
server->Cfunc(index);
|
||||||
info->len = -1;
|
}
|
||||||
server->msgLock.lock();
|
|
||||||
server->msgList.push_back(info);
|
|
||||||
server->msgLock.unlock();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (0 != server->ClienMap[index].c_strRecv) // recv
|
if (0 != clien->c_strRecv) // recv
|
||||||
{
|
{
|
||||||
// 接收到客户端消息
|
// 接收到客户端消息
|
||||||
msgInfo* info = new msgInfo;
|
int len = NumberOfBytes;
|
||||||
info->index = index;
|
char * buf = server->RecvBuff(index, clien->c_strRecv, len);
|
||||||
info->len = NumberOfBytes;
|
|
||||||
memcpy_s(info->buf, NumberOfBytes, server->ClienMap[index].c_strRecv, NumberOfBytes);
|
|
||||||
|
|
||||||
server->msgLock.lock();
|
while (buf)
|
||||||
server->msgList.push_back(info);
|
{
|
||||||
server->msgLock.unlock();
|
if (server->Rfunc != NULL)
|
||||||
|
{
|
||||||
memset(server->ClienMap[index].c_strRecv, 0, sizeof(server->ClienMap[index].c_strRecv));
|
server->Rfunc(index, buf, len);
|
||||||
|
}
|
||||||
|
delete buf;
|
||||||
|
len = 0;
|
||||||
|
buf = server->RecvBuff(index,NULL, len);
|
||||||
|
}
|
||||||
|
memset(clien->c_strRecv, 0, sizeof(clien->c_strRecv));
|
||||||
server->PostRecv(index); // 对自己投递接收
|
server->PostRecv(index); // 对自己投递接收
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -130,15 +136,42 @@ int SocketS::PostRecv(int index)
|
|||||||
|
|
||||||
int SocketS::PostSend(int index, const char* buf, int len)
|
int SocketS::PostSend(int index, const char* buf, int len)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ClienMap.find(index) != ClienMap.end())
|
if (ClienMap.find(index) != ClienMap.end())
|
||||||
{
|
{
|
||||||
|
lock_guard<std::mutex> guard(ClienMap[index].sendLock);
|
||||||
if (ClienMap[index].c_Sock != 0)
|
if (ClienMap[index].c_Sock != 0)
|
||||||
{
|
{
|
||||||
return send(ClienMap[index].c_Sock, buf, len, 0);
|
return send(ClienMap[index].c_Sock, buf, len, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* SocketS::RecvBuff(int index, char* buf, int& len)
|
||||||
|
{
|
||||||
|
char* buff = NULL;
|
||||||
|
MsgHead* h;
|
||||||
|
clienInfo* info = &ClienMap[index];
|
||||||
|
lock_guard<std::mutex> guard(info->msgLock);
|
||||||
|
if (len != 0)
|
||||||
|
memcpy_s(info->buf + info->buflen, len, buf, len);
|
||||||
|
info->buflen += len;
|
||||||
|
|
||||||
|
if (info->buflen > sizeof(MsgHead))
|
||||||
|
{
|
||||||
|
h = (MsgHead*)info->buf;
|
||||||
|
if (info->buflen - sizeof(MsgHead) >= h->bufLen)
|
||||||
|
{
|
||||||
|
buff = new char[h->bufLen + 1];
|
||||||
|
ZeroMemory(buff, h->bufLen + 1);
|
||||||
|
memcpy_s(buff, h->bufLen, info->buf + sizeof(MsgHead), h->bufLen);
|
||||||
|
len = h->bufLen;
|
||||||
|
info->buflen = info->buflen - len - sizeof(MsgHead);
|
||||||
|
if (info->buflen > 0)
|
||||||
|
memcpy_s(info->buf, info->buflen, info->buf + sizeof(MsgHead) + len, info->buflen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL SocketS::Creat(int Prot)
|
BOOL SocketS::Creat(int Prot)
|
||||||
@ -187,7 +220,7 @@ BOOL SocketS::Creat(int Prot)
|
|||||||
sockAddress.sin_family = AF_INET;
|
sockAddress.sin_family = AF_INET;
|
||||||
sockAddress.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // INADDR_ANY --- 任何地址都可以
|
sockAddress.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // INADDR_ANY --- 任何地址都可以
|
||||||
sockAddress.sin_port = htons(Prot);
|
sockAddress.sin_port = htons(Prot);
|
||||||
if (SOCKET_ERROR == bind(socketServer, (struct sockaddr*)&sockAddress, sizeof(sockAddress)))
|
if (SOCKET_ERROR == ::bind(socketServer, (struct sockaddr*)&sockAddress, sizeof(sockAddress)))
|
||||||
{
|
{
|
||||||
printf("bind 失败 error:%d\n", WSAGetLastError());
|
printf("bind 失败 error:%d\n", WSAGetLastError());
|
||||||
closesocket(socketServer);
|
closesocket(socketServer);
|
||||||
@ -232,7 +265,7 @@ BOOL SocketS::Creat(int Prot)
|
|||||||
|
|
||||||
if (0 != PostAccept())
|
if (0 != PostAccept())
|
||||||
{
|
{
|
||||||
Clear();
|
Close();
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -259,7 +292,7 @@ BOOL SocketS::Creat(int Prot)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketS::Clear()
|
void SocketS::Close()
|
||||||
{
|
{
|
||||||
g_flag = FALSE;
|
g_flag = FALSE;
|
||||||
for (auto i = ClienMap.begin(); i != ClienMap.end(); ++i)
|
for (auto i = ClienMap.begin(); i != ClienMap.end(); ++i)
|
||||||
@ -276,17 +309,69 @@ void SocketS::Clear()
|
|||||||
free(pThread);
|
free(pThread);
|
||||||
CloseHandle(hPort);
|
CloseHandle(hPort);
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
|
Rfunc = NULL;
|
||||||
|
Cfunc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketS::msgInfo* SocketS::GetMsg()
|
VOID SocketS::SetRecvFunc(function<VOID(int, char*, int)> fun)
|
||||||
{
|
{
|
||||||
msgInfo* info = NULL;
|
Rfunc = fun;
|
||||||
msgLock.lock();
|
|
||||||
if (msgList.size() > 0)
|
|
||||||
{
|
|
||||||
info = *msgList.begin();
|
|
||||||
msgList.pop_front();
|
|
||||||
}
|
|
||||||
msgLock.unlock();
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID SocketS::SetCloseFunc(function<VOID(int)> fun)
|
||||||
|
{
|
||||||
|
Cfunc = fun;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SocketS::GetClienName(int index, string& IP, int& Prot)
|
||||||
|
{
|
||||||
|
IP = "";
|
||||||
|
Prot = 0;
|
||||||
|
if(ClienMap.find(index)!= ClienMap.end())
|
||||||
|
{
|
||||||
|
if(ClienMap[index].c_Sock!=0)
|
||||||
|
{
|
||||||
|
struct sockaddr_in peerAddr;
|
||||||
|
int peerLen = sizeof(peerAddr);
|
||||||
|
getpeername(ClienMap[index].c_Sock, (struct sockaddr*)&peerAddr, &peerLen);
|
||||||
|
IP = inet_ntoa(peerAddr.sin_addr);
|
||||||
|
Prot = ntohs(peerAddr.sin_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int SocketS::Send(int index,const char* buf, int len)
|
||||||
|
{
|
||||||
|
MsgHead h;
|
||||||
|
h.bufLen = len;
|
||||||
|
time(&h.tm);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
lenth = -1;
|
||||||
|
}
|
||||||
|
return lenth;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SocketS::CloseClien(int index)
|
||||||
|
{
|
||||||
|
if (ClienMap.find(index) != ClienMap.end())
|
||||||
|
{
|
||||||
|
ClienMap[index].msgLock.lock();
|
||||||
|
WSACloseEvent(ClienMap[index].c_Olp.hEvent);
|
||||||
|
shutdown(ClienMap[index].c_Sock, SD_BOTH);
|
||||||
|
closesocket(ClienMap[index].c_Sock);
|
||||||
|
ClienMap[index].msgLock.unlock();
|
||||||
|
|
||||||
|
// ´ÓÊý×éÖÐɾµô
|
||||||
|
ClienMap[index].c_Sock = 0;
|
||||||
|
ClienMap[index].c_Olp.hEvent = NULL;
|
||||||
|
ClienMap.erase(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -10,45 +10,63 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#pragma comment(lib, "ws2_32.lib")
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
#pragma comment(lib, "Mswsock.lib")
|
#pragma comment(lib, "Mswsock.lib")
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
|
||||||
class SocketS
|
class SocketS
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct msgInfo
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
int len = 0;
|
|
||||||
char buf[1025] = { 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct clienInfo
|
struct clienInfo
|
||||||
{
|
{
|
||||||
SOCKET c_Sock;
|
SOCKET c_Sock;
|
||||||
OVERLAPPED c_Olp;
|
OVERLAPPED c_Olp;
|
||||||
|
int buflen = 0;
|
||||||
|
char buf[10240] = { 0 };
|
||||||
char c_strRecv[1024];
|
char c_strRecv[1024];
|
||||||
|
mutex msgLock; //消息锁
|
||||||
|
mutex sendLock; //消息锁
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MsgHead
|
||||||
|
{
|
||||||
|
int MyIndex = 0;
|
||||||
|
int bufLen = 0;
|
||||||
|
time_t tm = 0;
|
||||||
|
char token[34] = { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOL g_flag = TRUE; //状态
|
BOOL g_flag = TRUE; //状态
|
||||||
HANDLE hPort = NULL; //完成端口句柄
|
HANDLE hPort = NULL; //完成端口句柄
|
||||||
HANDLE* pThread = NULL; //线程句柄
|
HANDLE* pThread = NULL; //线程句柄
|
||||||
int g_count = 0; //当前客户端ID
|
int g_count = 0; //当前客户端ID
|
||||||
std::map<int, clienInfo>ClienMap; //所有客户端
|
map<int, clienInfo>ClienMap; //所有客户端
|
||||||
|
|
||||||
|
function<VOID(int,char*,int)> Rfunc = NULL;
|
||||||
|
function<VOID(int)> Cfunc = NULL;
|
||||||
|
|
||||||
std::mutex msgLock; //消息锁
|
|
||||||
std::list<msgInfo*>msgList; //存放所有消息
|
|
||||||
static DWORD WINAPI ThreadProc(LPVOID lpParameter); //工作者线程
|
static DWORD WINAPI ThreadProc(LPVOID lpParameter); //工作者线程
|
||||||
|
|
||||||
public:
|
|
||||||
SocketS();
|
|
||||||
int PostAccept(void);
|
int PostAccept(void);
|
||||||
int PostRecv(int index);
|
int PostRecv(int index);
|
||||||
int PostSend(int index, const char* buf, int len);
|
int PostSend(int index, const char* buf, int len);
|
||||||
|
char* RecvBuff(int index, char* buf, int& len);
|
||||||
|
public:
|
||||||
|
SocketS();
|
||||||
BOOL Creat(int Prot);
|
BOOL Creat(int Prot);
|
||||||
void Clear();
|
void Close();
|
||||||
msgInfo* GetMsg();
|
VOID SetRecvFunc(function<VOID(int, char*, int)> fun);
|
||||||
|
VOID SetCloseFunc(function<VOID(int)> fun);
|
||||||
|
VOID GetClienName(int index, string& IP, int& Prot);
|
||||||
|
int Send(int index, const char* buf, int len);
|
||||||
|
VOID CloseClien(int index);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
122
网络服务端/网络服务端.cpp
122
网络服务端/网络服务端.cpp
@ -1,4 +1,5 @@
|
|||||||
#include "SocketS.h"
|
#include "SocketS.h"
|
||||||
|
//#include "cst.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
struct clienMsg
|
struct clienMsg
|
||||||
@ -10,94 +11,55 @@ struct clienMsg
|
|||||||
char buf[1024];
|
char buf[1024];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MsgHead
|
||||||
|
{
|
||||||
|
int MyIndex = 0;
|
||||||
|
int SendIndex = 0;
|
||||||
|
int bufLen = 0;
|
||||||
|
time_t tm = 0;
|
||||||
|
//char token[34] = { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msgInfo
|
||||||
|
{
|
||||||
|
int buflen = 0;
|
||||||
|
char buf[10240] = { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
std::map<int/*name*/, int/*index*/> clienMap;
|
std::map<int/*name*/, int/*index*/> clienMap;
|
||||||
std::map<int/*index*/, int/*name*/> clienIndex;
|
std::map<int/*index*/, int/*name*/> clienIndex;
|
||||||
|
|
||||||
|
SocketS s;
|
||||||
|
int cont = 0;
|
||||||
|
VOID closeFunc(int index)
|
||||||
|
{
|
||||||
|
if (clienIndex.find(index) != clienIndex.end())
|
||||||
|
{
|
||||||
|
clienMap.erase(clienIndex[index]);
|
||||||
|
clienIndex.erase(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID recvFunc(int index, char* buf, int len)
|
||||||
|
{
|
||||||
|
//s.CloseClien(index);
|
||||||
|
//cout << buf;
|
||||||
|
string str = buf;
|
||||||
|
str += "\t";
|
||||||
|
str += to_string(cont++);
|
||||||
|
s.Send(index, str.c_str(), str.length());
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
SocketS s;
|
//s.SetRecvFunc([&tt](SocketS::msgInfo info) {return tt.ppp(info); });
|
||||||
|
s.SetCloseFunc(closeFunc);
|
||||||
|
s.SetRecvFunc(recvFunc);
|
||||||
s.Creat(6666);
|
s.Creat(6666);
|
||||||
// 阻塞
|
while(1)
|
||||||
SocketS::msgInfo* info;
|
|
||||||
clienMsg* msg;
|
|
||||||
while (1)
|
|
||||||
{
|
{
|
||||||
info = s.GetMsg();if (info)
|
Sleep(100);
|
||||||
{
|
|
||||||
if (info->len == -1)
|
|
||||||
{
|
|
||||||
if(clienMap.find(clienIndex[info->index])!= clienMap.end())
|
|
||||||
{
|
|
||||||
std::cout << clienIndex[info->index] << "退出登录\n";
|
|
||||||
clienMap.erase(clienIndex[info->index]);
|
|
||||||
clienIndex.erase(info->index);
|
|
||||||
}
|
|
||||||
delete info;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
msg = (clienMsg*)info->buf;
|
|
||||||
std::string buf;
|
|
||||||
buf = msg->buf;
|
|
||||||
switch (msg->code)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
std::cout << msg->myName << "请求登录\n";
|
|
||||||
if (clienMap.find(msg->myName) == clienMap.end())
|
|
||||||
{
|
|
||||||
if (buf == "123456")
|
|
||||||
{
|
|
||||||
clienMap[msg->myName] = info->index;
|
|
||||||
clienIndex[info->index] = msg->myName;
|
|
||||||
memcpy_s(msg->buf, sizeof("登录成功\0"), "登录成功\0", sizeof("登录成功\0"));
|
|
||||||
s.PostSend(info->index, (char*)msg, sizeof(clienMsg));
|
|
||||||
std::cout << msg->myName << "登录成功\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy_s(msg->buf, sizeof("密码错误\0"), "密码错误\0", sizeof("密码错误\0"));
|
|
||||||
s.PostSend(info->index, (char*)msg, sizeof(clienMsg));
|
|
||||||
std::cout << msg->myName << "登录失败\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy_s(msg->buf, sizeof("该账号已在其他地方登录\0"), "该账号已在其他地方登录\0", sizeof("该账号已在其他地方登录\0"));
|
|
||||||
s.PostSend(info->index, (char*)msg, sizeof(clienMsg));
|
|
||||||
std::cout << msg->myName << "登录失败\n";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
std::cout << msg->myName << "对" << msg->snedName << "说"<< msg->buf<<"\n";
|
|
||||||
if (clienMap.find(msg->snedName) == clienMap.end())
|
|
||||||
{
|
|
||||||
memcpy_s(msg->buf, sizeof("对方账号不在线\0"), "对方账号不在线\0", sizeof("对方账号不在线\0"));
|
|
||||||
msg->len = -1;
|
|
||||||
s.PostSend(info->index, (char*)msg, sizeof(clienMsg));
|
|
||||||
std::cout << msg->myName << "对" << msg->snedName << "消息发送失败\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(s.PostSend(clienMap[msg->snedName], info->buf, info->len)<=0)
|
|
||||||
{
|
|
||||||
memcpy_s(msg->buf, sizeof("消息发送失败\0"), "消息发送失败\0", sizeof("消息发送失败\0"));
|
|
||||||
msg->len = -1;
|
|
||||||
s.PostSend(info->index, (char*)msg, sizeof(clienMsg));
|
|
||||||
std::cout << msg->myName << "对" << msg->snedName << "消息发送失败\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
delete info;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Sleep(10);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
system("pause");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user