📄 dddlqserverdlg.cpp
字号:
long CDdDlqServerDlg::OnMySocket(WPARAM wParam, LPARAM lParam)
{
// 取得有事件发生的套节字句柄
SOCKET s = wParam;
// 查看是否出错
if(WSAGETSELECTERROR(lParam))
{
ddRemoveClient(s);
closesocket(s);
return 0;
}
// 处理发生的事件
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT: // 监听中的套接字检测到有连接进入
if(m_nClient < MAX_SOCKET)
{
// 接受连接请求,新的套节字client是新连接的套节字
SOCKET client = ::accept(s, NULL, NULL);
// 设置新的套节字为窗口通知消息类型
int i = WSAAsyncSelect(client,
m_hWnd, WM_MYSOCKET, FD_READ|FD_WRITE|FD_CLOSE);
ddAddClient(client);
}
else
{
MessageBox("连接客户太多!");
}
break;
case FD_CLOSE: // 检测到套接字对应的连接被关闭。
ddRemoveClient(s);
closesocket(s);
break;
case FD_READ: // 套接字接受到对方发送过来的数据包
{
// 取得对方的IP地址和端口号(使用getpeername函数)
// Peer对方的地址信息
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
getpeername(s, (SOCKADDR*)&sockAddr, &nSockAddrLen);
// 转化为主机字节顺序
int nPeerPort = ntohs(sockAddr.sin_port);
// 转化为字符串IP
CString sPeerIP = inet_ntoa(sockAddr.sin_addr);
// 取得对方的主机名称
// 取得网络字节顺序的IP值
DWORD dwIP = inet_addr(sPeerIP);
// 获取主机名称,注意其中第一个参数的转化
hostent* pHost = gethostbyaddr((LPSTR)&dwIP, 4, AF_INET);
char szHostName[256];
strncpy(szHostName, pHost->h_name, 256);
// 接受真正的网络数据
char szText[1024] = { 0 };
unsigned char ctrlWord;
recv(s, szText, 1024, 0);
ctrlWord = unsigned char (szText[0]);
if(ctrlWord == 0X01)//dial request
ddAnswerDialReq(s, szText);
if(ctrlWord == 0X02)//client update
ddxClientUpdate(szText);
// 显示给用户
//CString strItem = CString(szHostName) + "["+ sPeerIP+ "]: " + CString(szText);
// m_listInfo.InsertString(0, strItem);
break;
}
}
return 0;
}
BOOL CDdDlqServerDlg::ddAddClient(SOCKET s)
{
if(m_nClient < MAX_SOCKET)
{
// 添加新的成员
m_arClient[m_nClient++] = s;
return TRUE;
}
return FALSE;
}
void CDdDlqServerDlg::ddRemoveClient(SOCKET s)
{
BOOL bFind = FALSE;
for(int i=0; i<m_nClient; i++)
{
if(m_arClient[i] == s)
{
bFind = TRUE;
break;
}
}
// 如果找到就将此成员从列表中移除
if(bFind)
{
m_nClient--;
// 将此成员后面的成员都向前移动一个单位
for(int j=i; j<m_nClient; j++)
{
m_arClient[j] = m_arClient[j+1];
}
}
}
void CDdDlqServerDlg::ddCloseAllSocket()
{
// 关闭监听套节字
if(m_socket != INVALID_SOCKET)
{
::closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
// 关闭所有客户的连接
for(int i=0; i<m_nClient; i++)
{
::closesocket(m_arClient[i]);
}
m_nClient = 0;
}
void CDdDlqServerDlg::ddStartServer()
{
if(m_socket == INVALID_SOCKET) // 开启服务
{
// 取得端口号
CString sPort = "2345";
// GetDlgItem(IDC_PORT)->GetWindowText(sPort);
int nPort = atoi(sPort);
if(nPort < 1025 || nPort > 65535)
{
MessageBox("端口号错误!");
return;
}
// 创建监听套节字,使它进入监听状态
if(!ddCreateSocket(nPort))
{
MessageBox("启动服务出错!");
return;
}
// 设置相关子窗口控件状态
// GetDlgItem(IDC_START)->SetWindowText("停止服务");
m_bar.SetText(" 正在监听……", 0, 0);
// GetDlgItem(IDC_PORT)->EnableWindow(FALSE);
}
else // 停止服务
{
// 关闭所有连接
ddCloseAllSocket();
// 设置相关子窗口控件状态
// GetDlgItem(IDC_START)->SetWindowText("开启服务");
m_bar.SetText(" 空闲", 0, 0);
// GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
}
}
BOOL CDdDlqServerDlg::ddCreateSocket(int nPort)
{
if(m_socket == INVALID_SOCKET)
::closesocket(m_socket);
// 创建套节字
m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(m_socket == INVALID_SOCKET)
return FALSE;
// 填写要关联的本地地址
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.s_addr = INADDR_ANY;
// 绑定端口
if(::bind(m_socket, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
return FALSE;
}
// 设置socket为窗口通知消息类型
::WSAAsyncSelect(m_socket, m_hWnd, WM_MYSOCKET, FD_ACCEPT|FD_CLOSE);
// 进入监听模式
::listen(m_socket, 5);
return TRUE;
}
void ddGlSend2Client(SOCKET sckt, CString sData)
{
if(sckt == INVALID_SOCKET)
{
return;
}
// 取得要发送的字符串
CString sText;
// GetDlgItem(IDC_TEXT)->GetWindowText(sText);
sText = sData;
// 添加一个“回车换行”
// 注意,添加它并不是必须的,但是如果使用本软件作为客户端调试网络协议,
// 比如SMTP、FTP等,就要添加它了。因为这些协议都要求使用“回车换行”作为一个命令的结束标记
//sText += "\r\n";
// 发送数据到客户端
if(::send(sckt, sText, sText.GetLength(), 0) != -1)
{
//AddStringToList(sText, FALSE);
//GetDlgItem(IDC_TEXT)->SetWindowText("");
}
}
int CDdDlqServerDlg::ddAnswerDialReq(SOCKET s, char *szAnswerText)
{
CString strTmp;
CString urName, urPwd, urIP, urCurr;
BOOL bSuccess;
//strTmp = szAnswerText;
ddParseRecvMsg(szAnswerText, urName, urPwd, urIP, urCurr);
bSuccess = theApp.glFindPositionFromUserTable(urName);
if(!bSuccess)
return -1;
//theApp.adoRstUser.GetFieldValue("ddUserName", strTmp);
theApp.adoRstUser.GetFieldValue("ddUserPwd", strTmp);
if(strTmp != urPwd)
return -2;
theApp.adoRstUser.GetFieldValue("ddUserIP", strTmp);
if(strTmp != urIP)
return -3;
//theApp.adoRstUser.GetFieldValue("ddKaiHuYear", iy);
//theApp.adoRstUser.GetFieldValue("ddKaiHuMonth", im);
//theApp.adoRstUser.GetFieldValue("ddKaiHuDay", id);
//theApp.adoRstUser.GetFieldValue("ddDaoQiYear", iy);
//theApp.adoRstUser.GetFieldValue("ddDaoQiMonth", im);
//theApp.adoRstUser.GetFieldValue("ddDaoQiDay", id);
theApp.adoRstUser.GetFieldValue("ddCurrServer", strTmp);
if(strTmp != urCurr)
return -4;
//theApp.adoRstUser.GetFieldValue("ddUserAd", userInfo.uiAdv);
bSuccess = theApp.glFindPositionFromServerTable(urCurr);
if(!bSuccess)
return -5;
//theApp.adoRstServer.GetFieldValue("servName", strTmp);
//theApp.adoRstServer.GetFieldValue("servZaiXianRenShu", irenshu);
//theApp.adoRstServer.GetFieldValue("servZongRenShu", irenshu);
//theApp.adoRstServer.GetFieldValue("servStatus", strTmp);
theApp.adoRstServer.GetFieldValue("vpnServerIP", urIP);
theApp.adoRstServer.GetFieldValue("vpnUserName", urName);
theApp.adoRstServer.GetFieldValue("vpnUserPwd", urPwd);
if(ddFormatMessage(strTmp, urName, urPwd, urIP, urCurr) != 1)
return -6;
ddGlSend2Client(s, strTmp);
return 1;
}
int CDdDlqServerDlg::ddxClientUpdate(char *szUpdateText)
{
CString str;
CString urName, urPwd, urIP, urCurr;
str = szUpdateText;
ddParseRecvMsg(szUpdateText, urName, urPwd, urIP, urCurr);
return 1;
}
int CDdDlqServerDlg::ddFormatMessage(CString &strMsg, CString vpnName, CString vpnPwd, CString vpnIP, CString vpnCurr)
{
char szText[70] = {0};
int i, ilen;
ilen = vpnName.GetLength();
if((ilen < 1) || (ilen > 14))
return -1;
szText[0] = char(0X82);//byte[0] 1 byte
szText[1] = ilen;
for(i=0; i<ilen; i++)
szText[2 + i] = vpnName[i];
for(i=ilen; i<14; i++)//填满14个字节byte[1-15] 15 bytes
szText[2 + i] = '0';
ilen = vpnPwd.GetLength();//byte[16-30] 15 bytes
if((ilen < 1) || (ilen > 14))
return -2;
szText[16] = ilen;
for(i=0; i<ilen; i++)
szText[17 + i] = vpnPwd[i];
for(i=ilen; i<14; i++)//填满14个字节
szText[17 + i] = '0';
ilen = vpnIP.GetLength();//byte[31-46] 16bytes
if((ilen < 7) || (ilen > 15))
return -3;
szText[31] = ilen;
for(i=0; i<ilen; i++)
szText[32 + i] = vpnIP[i];
for(i=ilen; i<15; i++)//填满15个字节
szText[32 + i] = '0';
ilen = vpnCurr.GetLength();//byte[47-67] 21 bytes
if((ilen < 1) || (ilen > 14))
return -4;
szText[47] = ilen;
for(i=0; i<ilen; i++)
szText[48 + i] = vpnCurr[i];
for(i=ilen; i<20; i++)//填满20个字节
szText[48 + i] = '0';
szText[68] = '\0';
strMsg = szText;
return 1;
}
int CDdDlqServerDlg::ddParseRecvMsg(char *szMsg, CString &userName, CString &userPwd, CString &userIP, CString &userCurr)
{
CString strMsg;
char szText[21] = {0};
int i, ilen;
strMsg = szMsg;
if(strMsg.GetLength() != 68)
return -1;
//ilen = ddInterface.itfUseName.GetLength();//byte[1-15] 15 bytes
ilen = strMsg[1];
for(i=0; i<ilen; i++)
szText[i] = strMsg[2 + i];
szText[i] = '\0';
userName = szText;
//ilen = ddInterface.itfPassword.GetLength();//byte[16-30] 15 bytes
ilen = strMsg[16];
for(i=0; i<ilen; i++)
szText[i] = strMsg[17 + i];
szText[i] = '\0';
userPwd = szText;
//ilen = ddGetIPAddress(str, strIPAddress);byte[31-46] 16 bytes
ilen = strMsg[31];
for(i=0; i<ilen; i++)
szText[i] = strMsg[32 + i];
szText[i] = '\0';
userIP = szText;
//ilen = ddInterface.itfServerCurrent.GetLength();//byte[47-67] 21 bytes
ilen = strMsg[47];
for(i=0; i<ilen; i++)
szText[i] = strMsg[48 + i];
szText[i] = '\0';
userCurr = szText;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -