diff --git a/网络客户端/SocketC.cpp b/网络客户端/SocketC.cpp index 3625ded..0f737aa 100644 --- a/网络客户端/SocketC.cpp +++ b/网络客户端/SocketC.cpp @@ -73,46 +73,101 @@ bool SocketC::Connect(string IP, UINT Prot) VOID SocketC::Receive() { + char* buff = NULL; while(state) { - MsgInfo* info = new MsgInfo; - info->len = recv(sclient, info->buff, 2047, 0); - msgLock.lock(); - msgList.push_back(info); - msgLock.unlock(); + char buf[2048] = { 0 }; + int len = recv(sclient, buf, 2048, 0); + if (len ==SOCKET_ERROR || len == 0) + { + 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; } -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 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; - msgLock.lock(); - if (msgList.size() > 0) + 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, Date, len); + int lenth = send(sclient, buff, len + sizeof(MsgHead), 0) - sizeof(MsgHead); + delete[] buff; + if (lenth < 0) { - info = *msgList.begin(); - msgList.pop_front(); + lenth = -1; } - msgLock.unlock(); - return info; + return lenth; +} + +VOID SocketC::SetRecvFunc(function fun) +{ + Rfunc = fun; +} + +VOID SocketC::SetCloseFunc(function fun) +{ + Cfunc = fun; } void SocketC::Close() { - state = 0; - //ر׽ - closesocket(sclient); - //ͷDLLԴ + if (state != 0) + { + state = 0; + //ر׽ + shutdown(sclient, SD_BOTH); + closesocket(sclient); + //ͷDLLԴ + rec.join(); + } WSACleanup(); - //for (size_t i = 0; i < msgList.size(); i++) - //{ - // - //} - msgList.clear(); - rec.join(); } diff --git a/网络客户端/SocketC.h b/网络客户端/SocketC.h index e39fc6a..9b6262f 100644 --- a/网络客户端/SocketC.h +++ b/网络客户端/SocketC.h @@ -3,9 +3,8 @@ #include #include #include -#include #include -#include +#include #pragma comment(lib,"ws2_32.lib") @@ -13,24 +12,34 @@ using namespace std; class SocketC { -public: - struct MsgInfo - { - int len = 0; //ݳ - char buff[2048] = {0}; //Ϣ - }; 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; - std::listmsgList; BOOL state = 0; std::thread rec; std::mutex msgLock; + function Rfunc = NULL; + function Cfunc = NULL; bool initSocket(); VOID Receive(); + char* RecvBuff(char* buf, int& len); + + public: ~SocketC(); bool Connect(string IP, UINT Prot); int Send(const char* Date, int len); - MsgInfo* GetMsg(); + + VOID SetRecvFunc(function fun); + VOID SetCloseFunc(function fun); void Close(); }; diff --git a/网络客户端/网络客户端.cpp b/网络客户端/网络客户端.cpp index 20f6719..dcb4950 100644 --- a/网络客户端/网络客户端.cpp +++ b/网络客户端/网络客户端.cpp @@ -1,135 +1,42 @@ #include #include "SocketC.h" +#include using namespace std; -struct clienMsg -{ - int myName; - int snedName; - int code; - int len; - char buf[1024]; -}; - - - - SocketC c; int flag = 1; int myName = 0; -VOID LogIn() { - if (myName != 0) - { - cout << "当前已登录无需重复登录,当前账号:"<> 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() +void recvFunc(char* buf, int len) { - if (myName == 0) - { - cout << "请先登录账号\n"; - return; - } - 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)); + cout << buf << "\n"; +} +void closeFunc() +{ + cout << "服务器断开连接"; } int main() { + c.SetRecvFunc(recvFunc); + c.SetCloseFunc(closeFunc); c.Connect("127.0.0.1", 6666); - - thread th([] { - 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) + string str; + for (int i = 0; i < 10000000; i++) { - cin >> code; - switch (code) + str = to_string(i); + c.Send(str.c_str(), str.length()); + if (i % 100 == 0) { - case 1: - LogIn(); - break; - - case 2: - SendMsg(); - break; - default: - flag = 0; - th.join(); - c.Close(); - return 0; + Sleep(100); } } + Sleep(10); + c.Close(); + while (1) + { + Sleep(1000); + } } \ No newline at end of file diff --git a/网络服务端/SocketS.cpp b/网络服务端/SocketS.cpp index ad4447d..fb500e4 100644 --- a/网络服务端/SocketS.cpp +++ b/网络服务端/SocketS.cpp @@ -13,23 +13,26 @@ DWORD WINAPI SocketS::ThreadProc(LPVOID lpParameter) while (server->g_flag) { BOOL bFlag = GetQueuedCompletionStatus(port, &NumberOfBytes, &index, &lpOverlapped, INFINITE); + clienInfo* clien = &server->ClienMap[index]; + if (FALSE == bFlag) { if (64 == GetLastError()) { printf("ͻ쳣\n"); - msgInfo* info = new msgInfo; - info->index = index; - info->len = -1; - server->msgLock.lock(); - server->msgList.push_back(info); - server->msgLock.unlock(); + clien->c_Sock = 0; + clien->c_Olp.hEvent = NULL; + server->ClienMap.erase(index); + if (server->Cfunc != NULL) + { + server->Cfunc(index); + } } continue; } // ദ - + //lock_guard guard(clien->msgLock); if (0 == index) // accept { printf("accept\n"); @@ -39,6 +42,7 @@ DWORD WINAPI SocketS::ThreadProc(LPVOID lpParameter) { printf("CreateIoCompletionPort ʧ error:%d\n", GetLastError()); closesocket(server->ClienMap[server->g_count].c_Sock); + continue; } server->PostRecv(server->g_count); // Ͷrecv @@ -51,39 +55,41 @@ DWORD WINAPI SocketS::ThreadProc(LPVOID lpParameter) { printf("ͻ\n"); - closesocket(server->ClienMap[index].c_Sock); - WSACloseEvent(server->ClienMap[index].c_Olp.hEvent); + closesocket(clien->c_Sock); + WSACloseEvent(clien->c_Olp.hEvent); // ɾ - server->ClienMap[index].c_Sock = 0; - server->ClienMap[index].c_Olp.hEvent = NULL; + clien->c_Sock = 0; + clien->c_Olp.hEvent = NULL; server->ClienMap.erase(index); - - msgInfo* info = new msgInfo; - info->index = index; - info->len = -1; - server->msgLock.lock(); - server->msgList.push_back(info); - server->msgLock.unlock(); + if (server->Cfunc != NULL) + { + server->Cfunc(index); + } } else { - if (0 != server->ClienMap[index].c_strRecv) // recv + if (0 != clien->c_strRecv) // recv { // յͻϢ - msgInfo* info = new msgInfo; - info->index = index; - info->len = NumberOfBytes; - memcpy_s(info->buf, NumberOfBytes, server->ClienMap[index].c_strRecv, NumberOfBytes); + int len = NumberOfBytes; + char * buf = server->RecvBuff(index, clien->c_strRecv, len); - server->msgLock.lock(); - server->msgList.push_back(info); - server->msgLock.unlock(); - - memset(server->ClienMap[index].c_strRecv, 0, sizeof(server->ClienMap[index].c_strRecv)); + while (buf) + { + if (server->Rfunc != NULL) + { + 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); // ԼͶݽ } } } + } return 0; @@ -130,15 +136,42 @@ int SocketS::PostRecv(int index) int SocketS::PostSend(int index, const char* buf, int len) { - if (ClienMap.find(index) != ClienMap.end()) { + lock_guard guard(ClienMap[index].sendLock); if (ClienMap[index].c_Sock != 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 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) @@ -187,7 +220,7 @@ BOOL SocketS::Creat(int Prot) sockAddress.sin_family = AF_INET; sockAddress.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // INADDR_ANY --- κεַ 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()); closesocket(socketServer); @@ -232,7 +265,7 @@ BOOL SocketS::Creat(int Prot) if (0 != PostAccept()) { - Clear(); + Close(); WSACleanup(); return -1; } @@ -259,7 +292,7 @@ BOOL SocketS::Creat(int Prot) } -void SocketS::Clear() +void SocketS::Close() { g_flag = FALSE; for (auto i = ClienMap.begin(); i != ClienMap.end(); ++i) @@ -276,17 +309,69 @@ void SocketS::Clear() free(pThread); CloseHandle(hPort); WSACleanup(); + Rfunc = NULL; + Cfunc = NULL; } -SocketS::msgInfo* SocketS::GetMsg() +VOID SocketS::SetRecvFunc(function fun) { - msgInfo* info = NULL; - msgLock.lock(); - if (msgList.size() > 0) - { - info = *msgList.begin(); - msgList.pop_front(); - } - msgLock.unlock(); - return info; + Rfunc = fun; } + +VOID SocketS::SetCloseFunc(function 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); + } +} + diff --git a/网络服务端/SocketS.h b/网络服务端/SocketS.h index 9520ada..d2dd207 100644 --- a/网络服务端/SocketS.h +++ b/网络服务端/SocketS.h @@ -10,45 +10,63 @@ #include #include #include +#include +#include #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "Mswsock.lib") +using namespace std; + +#pragma warning(disable:4996) + class SocketS { public: - struct msgInfo - { - int index; - int len = 0; - char buf[1025] = { 0 }; - }; - private: struct clienInfo { SOCKET c_Sock; OVERLAPPED c_Olp; + int buflen = 0; + char buf[10240] = { 0 }; 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; //״̬ HANDLE hPort = NULL; //ɶ˿ھ HANDLE* pThread = NULL; //߳̾ int g_count = 0; //ǰͻID - std::mapClienMap; //пͻ + mapClienMap; //пͻ + + function Rfunc = NULL; + function Cfunc = NULL; - std::mutex msgLock; //Ϣ - std::listmsgList; //Ϣ static DWORD WINAPI ThreadProc(LPVOID lpParameter); //߳ -public: - SocketS(); int PostAccept(void); int PostRecv(int index); int PostSend(int index, const char* buf, int len); + char* RecvBuff(int index, char* buf, int& len); +public: + SocketS(); BOOL Creat(int Prot); - void Clear(); - msgInfo* GetMsg(); + void Close(); + VOID SetRecvFunc(function fun); + VOID SetCloseFunc(function fun); + VOID GetClienName(int index, string& IP, int& Prot); + int Send(int index, const char* buf, int len); + VOID CloseClien(int index); + }; diff --git a/网络服务端/网络服务端.cpp b/网络服务端/网络服务端.cpp index b625e1f..090ec34 100644 --- a/网络服务端/网络服务端.cpp +++ b/网络服务端/网络服务端.cpp @@ -1,4 +1,5 @@ #include "SocketS.h" +//#include "cst.h" #include struct clienMsg @@ -10,94 +11,55 @@ struct clienMsg 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 clienMap; std::map 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) { - SocketS s; + //s.SetRecvFunc([&tt](SocketS::msgInfo info) {return tt.ppp(info); }); + s.SetCloseFunc(closeFunc); + s.SetRecvFunc(recvFunc); s.Creat(6666); - // 阻塞 - SocketS::msgInfo* info; - clienMsg* msg; - while (1) + while(1) { - info = s.GetMsg();if (info) - { - 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); - } + Sleep(100); } - - system("pause"); return 0; }