📄 maindlg.cpp
字号:
local.sin_family = AF_INET;
local.sin_port = htons(LocalListenPort);
local.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(m_ListenSock, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)
{
m_hWndStatusBar.SetWindowText("bind() failed");
closesocket(m_ListenSock);
return false;
}
if (listen(m_ListenSock, MAX_CONNECT) == SOCKET_ERROR) //最大连接数量
{
m_hWndStatusBar.SetWindowText("listen() failed");
closesocket(m_ListenSock);
return false;
}
if (WSAAsyncSelect(m_ListenSock, m_hWnd, WM_SOCKET_CONN, FD_ACCEPT) == SOCKET_ERROR)
{
m_hWndStatusBar.SetWindowText("WSAAsyncSelect() failed");
closesocket(m_ListenSock);
return false;
}
CString text;
text.Format("开始监听端口 %d", LocalListenPort);
m_hWndStatusBar.SetWindowText(text);
return true;
}
void CMainDlg::AddHost(SOCKET s, CHAR HostType)
{
struct sockaddr_in host;
int iAddrSize = sizeof(host);
CString message;
PHOST_LIST_LINK p = NULL;
getpeername(s, (struct sockaddr *)&host, &iAddrSize);
if (HostType == 1)
{
for (p = m_host; p != NULL; p = p->Next)
{
if (p->Address.S_un.S_addr == host.sin_addr.S_un.S_addr && p->Type == 1) //静态主机不重复添加
break;
}
}
if (p == NULL)
{
p = new HOST_LIST_LINK;
if (p == NULL)
{
closesocket(s);
return;
}
p->Sock = INVALID_SOCKET;
p->Address = host.sin_addr;
p->Port = host.sin_port;
p->CreateTime = GetTickCount();
p->Sid = m_nSessionTotal++;
p->Lock = LOCKED_STATUS_NONE;
p->Type = HostType; //被动连接为0,主动连接为1
p->Info = NULL;
p->Password[0] = 0;
p->Next = m_host; //放入主机链表中
m_host = p;
int nItem = m_hWndList.GetItemCount();
m_hWndList.InsertItem(LVIF_TEXT | LVIF_PARAM, nItem, inet_ntoa(host.sin_addr), 0, 0, 0, (LPARAM)p);
SYSTEMTIME stime;
GetLocalTime(&stime);
message.Format("%02d:%02d:%02d", stime.wHour, stime.wMinute, stime.wSecond);
m_hWndList.SetItemText(nItem, 2, message); //记录连上时间
m_hWndList.SetItemText(nItem, 3, "读取信息中"); //记录控制连接状态
}
if (p->Sock != INVALID_SOCKET)
closesocket(p->Sock);
p->Sock = s;
WSAAsyncSelect(s, m_hWnd, WM_SOCKET_CTRL, FD_READ | FD_CLOSE); //与被控端进入通信状态
int temp = CONTROL_QUERYINFO;
SimplySendPack(s, (char *)&temp, sizeof(temp));
p->Lock = LOCKED_STATUS_QUERY;
}
void CMainDlg::AddHost(char *host, int port)
{
struct in_addr address;
struct hostent *host1;
address.S_un.S_addr = inet_addr(host);
if (address.S_un.S_addr == INADDR_NONE)
{
host1 = gethostbyname(host); //解析主机域名
if (host1 == NULL)
{
return;
}
else
{
address.S_un.S_addr = *(DWORD *)(host1->h_addr_list[0]);
}
}
SOCKET s = ConnectSlave(address, htons(port), 1);
}
void CMainDlg::RemoveHost(SOCKET s)
{
PHOST_LIST_LINK *pp = &m_host;
while (*pp != NULL)
{
if ((*pp)->Sock == s) //取出主机记录
break;
pp = &(*pp)->Next;
}
if (*pp == NULL)
{
closesocket(s);
return;
}
if ((*pp)->Type == 1) //忽略静态主机
{
if ((*pp)->Sock != INVALID_SOCKET)
closesocket((*pp)->Sock);
(*pp)->Sock = INVALID_SOCKET;
return;
}
LV_FINDINFO FindInfo;
FindInfo.flags = LVFI_PARAM;
FindInfo.lParam = (LPARAM)*pp;
int nItem = m_hWndList.FindItem(&FindInfo, -1);
if (nItem != -1)
{
m_hWndList.DeleteItem(nItem); //从列表控件中移除
CString message;
message.Format("远程主机 %s 关闭了现有的控制连接", inet_ntoa((*pp)->Address));
m_hWndStatusBar.SetWindowText(message);
}
closesocket((*pp)->Sock);
PHOST_LIST_LINK p = *pp;
*pp = (*pp)->Next; //从主机链表中移除
if (p->Info != NULL)
delete [] p->Info;
delete p;
}
LRESULT CMainDlg::OnRequestConnect(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
PREQUEST_CONNECT prc = (PREQUEST_CONNECT)lParam;
PHOST_LIST_LINK p = (PHOST_LIST_LINK)prc->lpCtrlHandle;
if (m_nWaiting >= sizeof(connmgr) / sizeof(CONNECT_SOCK_MGR))
{
::PostMessage(prc->hAcceptWnd, WM_CONNECT_TIMEOUT, INVALID_SOCKET, (LPARAM)prc->lpParam);
return 0;
}
//添加一个连接请求到连接等待列表中
connmgr[m_nWaiting].hAcceptWnd = prc->hAcceptWnd;
connmgr[m_nWaiting].funBack = prc->funBack;
connmgr[m_nWaiting].lpParam = prc->lpParam;
connmgr[m_nWaiting].bRequestSended = FALSE;
connmgr[m_nWaiting].dwWorkType = prc->dwWorkType;
connmgr[m_nWaiting].dwHost = p->Address.S_un.S_addr;
connmgr[m_nWaiting++].dwReqTime = GetTickCount();
if (p->Type == 0)
{
DWORD temp = CONTROL_NEWCONNECT; //要求被控端创建一个新的连接
SimplySendPack(p->Sock, (char *)&temp, sizeof(temp));
}
else
{
ConnectSlave(p->Address, p->Port, 2);
}
return 0;
}
LRESULT CMainDlg::OnCancelRequest(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
PREQUEST_CONNECT prc = (PREQUEST_CONNECT)lParam;
for (int i = 0; i < m_nWaiting; i++)
{
if (connmgr[i].dwHost == ((PHOST_LIST_LINK)prc->lpCtrlHandle)->Address.S_un.S_addr)
{
connmgr[i] = connmgr[--m_nWaiting];
return 0;
}
}
return 0;
}
void CMainDlg::SendRequest(SOCKET s)
{
struct sockaddr_in host;
int iAddrSize = sizeof(host);
getpeername(s, (struct sockaddr *)&host, &iAddrSize);
for (int i = 0; i < m_nWaiting; i++)
{
//取出一个未发送的请求
if (connmgr[i].dwHost == host.sin_addr.S_un.S_addr && connmgr[i].bRequestSended == FALSE)
{
connmgr[i].bRequestSended = TRUE;
SimplySendPack(s, (char *)&connmgr[i].dwWorkType, sizeof(connmgr[i].dwWorkType));
return;
}
}
closesocket(s);
}
void CMainDlg::CompleteRequest(SOCKET s, DWORD work)
{
struct sockaddr_in host;
int iAddrSize = sizeof(host);
int xhost = -1;
getpeername(s, (struct sockaddr *)&host, &iAddrSize);
for (int i = 0; i < m_nWaiting; i++)
{
if (connmgr[i].dwHost == host.sin_addr.S_un.S_addr && connmgr[i].dwWorkType == work)
{
if (connmgr[i].bRequestSended == TRUE)
{
if (connmgr[i].funBack != NULL)
{
connmgr[i].funBack(s, connmgr[i].lpParam);
connmgr[i] = connmgr[--m_nWaiting];
return;
}
else if (::IsWindow(connmgr[i].hAcceptWnd))
{
::PostMessage(connmgr[i].hAcceptWnd, WM_CONNECT_COMPLETE, s, (LPARAM)connmgr[i].lpParam);
connmgr[i] = connmgr[--m_nWaiting];
return;
}
else
{
//无法返回结果给调用者
connmgr[i] = connmgr[--m_nWaiting];
closesocket(s);
return;
}
}
else
{
if (xhost == -1)
xhost = i;
}
}
}
if (xhost != -1)
{
if (connmgr[xhost].funBack != NULL)
{
connmgr[xhost].funBack(s, connmgr[xhost].lpParam);
connmgr[xhost] = connmgr[--m_nWaiting];
return;
}
else if (::IsWindow(connmgr[xhost].hAcceptWnd))
{
::PostMessage(connmgr[xhost].hAcceptWnd, WM_CONNECT_COMPLETE, s, (LPARAM)connmgr[xhost].lpParam);
connmgr[xhost] = connmgr[--m_nWaiting];
return;
}
else
{
//无法返回结果给调用者
connmgr[xhost] = connmgr[--m_nWaiting];
closesocket(s);
return;
}
}
//连接主机无等待记录,丢弃该连接
closesocket(s);
}
void CMainDlg::CloseContrlSock(SOCKET s, LPVOID lpParam)
{
closesocket(s);
}
void CMainDlg::UpdateHostInfo(SOCKET s)
{
PHOST_LIST_LINK p = NULL;
for (p = m_host; p != NULL; p = p->Next)
{
if (p->Type == 1) //更新静态主机信息
{
if (p->Sock == INVALID_SOCKET)
ConnectSlave(p->Address, p->Port, 1);
else
AddHost(p->Sock, 1);
}
}
}
SOCKET CMainDlg::ConnectSlave(struct in_addr address, int port, int type)
{
struct sockaddr_in slave;
long temp, ret;
SOCKET slave_sock;
slave.sin_family = AF_INET;
slave.sin_port = port;
slave.sin_addr = address;
slave_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (slave_sock == INVALID_SOCKET)
return INVALID_SOCKET;
if (connect(slave_sock, (struct sockaddr *)&slave, sizeof(slave)) == SOCKET_ERROR)
{
closesocket(slave_sock);
return INVALID_SOCKET;
}
CString message;
message.Format("连接到主机 %s", inet_ntoa(slave.sin_addr));
m_hWndStatusBar.SetWindowText(message);
if (type == 1)
temp = CONN3_MASTER_ANSWER;
else
temp = CONN4_MASTER_ANSWER;
ret = send(slave_sock, (char *)&temp, sizeof(temp), 0);
if (ret != sizeof(temp))
{
closesocket(slave_sock);
return INVALID_SOCKET;
}
WSAAsyncSelect(slave_sock, this->m_hWnd, WM_SOCKET_CONN, FD_READ | FD_WRITE | FD_CLOSE);
// ret = recv(slave_sock, (char *)&temp, sizeof(temp), 0);
// if (ret != sizeof(temp) || temp != CONN3_SLAVE_OK)
// {
// closesocket(slave_sock);
// return INVALID_SOCKET;
// }
return slave_sock;
}
char *CMainDlg::SimplyRecvPack(SOCKET s)
{
PACK_TYPE_1 pack;
int ret = recv(s, (char *)&pack, sizeof(PACK_TYPE_1), MSG_PEEK); //读取包头部
if (ret != sizeof(PACK_TYPE_1))
return NULL;
if (pack.dwPackType != 0)
return NULL;
char *buf = new char[sizeof(PACK_TYPE_1) + pack.nPackSize];
if (buf == NULL)
return NULL;
ret = recv(s, buf, sizeof(PACK_TYPE_1) + pack.nPackSize, MSG_PEEK); //尝试读取全部数据
if (ret != (int)(sizeof(PACK_TYPE_1) + pack.nPackSize))
{
delete [] buf;
return NULL;
}
ret = recv(s, (char *)&pack, sizeof(PACK_TYPE_1), 0);
ret = recv(s, buf, pack.nPackSize, 0); //等待数据包全部到达系统缓冲区再读取
return buf;
}
void CMainDlg::SimplySendPack(SOCKET s, char *p, int l)
{
PPACK_TYPE_1 pack = (PPACK_TYPE_1)new char[sizeof(PACK_TYPE_1) + l];
pack->dwPackType = 0;
pack->nPackSize = l;
memcpy(pack->bPackData, p, l);
send(s, (char *)pack, sizeof(PACK_TYPE_1) + l, 0);
delete [] pack;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -