#include "ServerSocket.h"
|
|
ServerSocket::ServerSocket()
|
{
|
if (initSocket()) cout << "Socket init successed!" << endl;
|
else cout << "Socket init failed!" << endl;
|
}
|
|
ServerSocket::~ServerSocket()
|
{
|
closesocket(m_server);
|
WSACleanup();
|
}
|
|
bool ServerSocket::initSocket()
|
{
|
WSAData wsa;
|
int val = WSAStartup(MAKEWORD(2, 2), &wsa);
|
if (val != 0)
|
{
|
cout << "WSAStartup failed!"<<endl;
|
}
|
|
m_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
SOCKADDR_IN addr;
|
addr.sin_family = AF_INET;
|
addr.sin_port = htons(PORT); //´¦Àí´óС¶Ë
|
addr.sin_addr.S_un.S_addr = 0;
|
int ret_bind = bind(m_server, (sockaddr*)&addr, sizeof(addr));
|
if (ret_bind) {
|
cout << "bind fail:" << WSAGetLastError() << endl;
|
return false;
|
}
|
int ret_listen = listen(m_server, 5);
|
if (ret_listen) {
|
cout << "listen fail:" << WSAGetLastError() << endl;
|
return false;
|
}
|
thread accept_thread(&ServerSocket::acceptThread, this);
|
accept_thread.detach(); // ·ÀÖ¹Òì³£½áÊø
|
|
thread mMap_Delete(&ServerSocket::mMapDelete, this);
|
mMap_Delete.detach();
|
|
return true;
|
}
|
|
void ServerSocket::acceptThread()
|
{
|
while (true) {
|
SOCKET client;
|
SOCKADDR_IN addr;
|
int len = sizeof(addr);
|
cout << "waiting for connect..." << endl;
|
client = accept(m_server, (sockaddr*)&addr, &len);
|
cout << "client:" << client << endl;
|
if (client == SOCKET_ERROR) {
|
cout << "socket Òì³£" << WSAGetLastError() << endl;
|
break;
|
}
|
else if (client == 0) {
|
cout << "socket ÒѹرÕ:" << WSAGetLastError() << endl;
|
break;
|
}
|
// Õý³£ Á¬ÉÏÁË
|
// Æô¶¯³¤Á¬½ÓỊ̈߳¬½øÐн»»¥
|
mMapInsert(client);
|
|
thread heart_check(&ServerSocket::heartBeatThread, this, client);
|
heart_check.detach();
|
|
thread recv_send(&ServerSocket::recvAndSendThread, this, client);
|
recv_send.detach();
|
|
}
|
}
|
|
void ServerSocket::recvAndSendThread(SOCKET client)
|
{
|
while (true)
|
{
|
// ½â¾öÕ³°üÎÊÌ⣬˳´øÒ²½â¾öÁ˲ð°üÎÊÌâ
|
char* buffer = new char[sizeof(Head)];
|
int len_recv = recv(client, buffer, sizeof(Head), 0);
|
int head_rest = sizeof(Head) - len_recv; // Ê£Ó೤¶È
|
while (head_rest > 0) { // ±£Ö¤Êý¾ÝÍ·Äܹ»È«ÊÕµ½
|
len_recv = recv(client, buffer + (sizeof(Head) - head_rest), head_rest, 0);
|
head_rest -= len_recv;
|
}
|
Head* head = (Head*)buffer; // ת³É¶ÔÓ¦½á¹¹Ì壬ÔÙÈ¡³ö·â°ü×ܳ¤¶È
|
int len_total = head->len;
|
//int len_total = *(int*)(buffer + 4); // »¹¿ÉÒÔÖ±½ÓתΪHead*£¬Ö¸³ö³¤¶È
|
char* buffer_all = new char[len_total];
|
memcpy(buffer_all, buffer, sizeof(Head)); // ¿½±´Êý¾ÝÍ·½ø×ܵĻº³åÇø
|
|
int len_rest = len_total - sizeof(Head);
|
while (len_rest > 0) { // ±£Ö¤Êý¾ÝÌåÄܹ»È«²¿ÊÕµ½
|
len_recv = recv(client, buffer_all + (len_total - len_rest), len_rest, 0);
|
len_rest -= len_recv;
|
}
|
|
// Õý³£
|
//m_clientMap[client] = HEART_CHECK_TIMES; // ÖØÖÃÐÄÌøãÐÖµ
|
|
int type = *(int*)buffer;
|
if (type == 110) {
|
/*TestSturct2* ts2 = (TestSturct2*)buffer_all; // ת»»Ê±£¬Ê¹ÓÃ×ܵÄbuffer_all
|
if (ts2) {
|
ts2->a = (char*)ts2 + sizeof(TestSturct2);
|
ts2->b = ts2->a + strlen(ts2->a) + 1;
|
cout << ts2->len;
|
cout << "ÄÚÈÝ1: " << ts2->a << endl;
|
cout << "ÄÚÈÝ2: " << ts2->b << endl;
|
}*/
|
}
|
/*else if (type == LOGIN_REQ) {
|
// µÇ¼ÇëÇó
|
LoginReq* req = (LoginReq*)buffer_all; // ת»»Ê±£¬Ê¹ÓÃ×ܵÄbuffer_all
|
cout << "Óû§ÐÅÏ¢:" << req->user_name << " " << req->password << endl;
|
Login login;
|
login.business(req, client); // µ÷ÓÃÒµÎñ´¦ÀíAPI
|
}*/
|
if (type == HEART_CHECK_REQ) {
|
// ÊÕµ½ÐÄÌøÇëÇó°ü£¬»ØÏìÓ¦°ü
|
HeartCheckRes res;
|
send(client, (char*)&res, res.len, 0);
|
cout << "Òѻظ´°ü£¡" << endl;
|
}
|
|
// Ô·â²»¶¯µÄ»Ø°ü
|
//send(client, buffer_all, len_total, 0);
|
|
// ÓÃÍêÁË£¬¼ÇµÃÊͷŶ¯Ì¬¿ª±ÙµÄÄÚ´æ
|
if (buffer)
|
{
|
delete[] buffer;
|
buffer = nullptr; // ·ÀÖ¹Ö¸ÕëÐü¿Õ£¬¶ø²úÉúÐü¿ÕÖ¸Õë
|
}
|
if (buffer_all) {
|
delete[] buffer_all;
|
buffer_all = nullptr;
|
}
|
|
}
|
}
|
|
void ServerSocket::heartBeatThread(SOCKET client)
|
{
|
while (true)
|
{
|
Sleep(HEARTBEAT_INTERVAL * 1000);
|
mutex heartLock;
|
lock_guard<std::mutex> lock(heartLock);
|
--m_clientMap[client];
|
|
}
|
}
|
|
void ServerSocket::mMapInsert(SOCKET client)
|
{
|
lock_guard<mutex> lg(m_mutex);
|
m_clientMap.insert(make_pair(client, HEART_CHECK_TIMES));
|
cout << "²åÈë³É¹¦£ºtimes = " << m_clientMap[client] << endl;
|
}
|
|
void ServerSocket::mMapUpdate(SOCKET client)
|
{
|
lock_guard<mutex> lg(m_mutex);
|
m_clientMap.insert(make_pair(client, HEART_CHECK_TIMES));
|
}
|
|
void ServerSocket::mMapDelete()
|
{
|
while (true)
|
{
|
Sleep(HEARTBEAT_INTERVAL * 1000);
|
lock_guard<std::mutex> lock(m_mutex);
|
for (auto& client_socket : m_clientMap) {
|
cout << client_socket.second << endl;
|
if (client_socket.second <= 0) {
|
closesocket(client_socket.first);
|
m_clientMap.erase(client_socket.first);
|
cout << "ɾ³ýÁ¬½Ó³É¹¦" << endl;
|
}
|
}
|
}
|
}
|