?? netcmt.cpp
字號:
// NetCmt.cpp: implementation of the CNetCmt class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "NetCmt.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define MAX_SOCKETBUFFER 1024
//監聽線程函數體
//There are two prototype of server socket, one is for large data flow
//another is for little data flow
//here I adopted the first one, which will cost more system resource
UINT ListenThread(LPVOID pParam)
{
SOCKETLISTENPARAM *psockparam=(SOCKETLISTENPARAM*)pParam;
sockaddr_in from;
int fromlen = sizeof(from);
//線程將會在下面這個函數阻塞,直到有客戶端連接進來
SOCKET ClientSocket = accept(psockparam->listen_socket,(struct sockaddr*)&from,&fromlen);
//判斷是否連接上
if (ClientSocket == INVALID_SOCKET)
{
int iErr = WSAGetLastError();
if (iErr != WSAEINTR)
{
AfxBeginThread(ListenThread,pParam);
}
return 0L;
}
//生成一個ip字符串,后邊用
CString strIP;
strIP.Format("%d.%d.%d.%d",
from.sin_addr.S_un.S_un_b.s_b1,
from.sin_addr.S_un.S_un_b.s_b2,
from.sin_addr.S_un.S_un_b.s_b3,
from.sin_addr.S_un.S_un_b.s_b4);
//連接成功,新開啟一個監聽線程
AfxBeginThread(ListenThread,pParam);
//將連接客戶端信息添加到通訊主體的客戶端列表里
if (psockparam->pListener->GetClientList() != NULL)
{
CLIENTINFO *pInfo = new CLIENTINFO;
memset(pInfo->fromip,0,sizeof(char)*16);
pInfo->socket = ClientSocket;
pInfo->fromport = from.sin_port;
strcpy(pInfo->fromip,strIP.GetBuffer(strIP.GetLength()));
psockparam->pListener->GetClientList()->AddTail(pInfo);
psockparam->pListener->AferConnect(pInfo);
}
//分配一個緩沖區接收數據
char *buffer=new char[MAX_SOCKETBUFFER];
while (1)
{
//線程將會堵塞在這個函數里直到收到數據
int irecv = recv(ClientSocket,buffer,MAX_SOCKETBUFFER,0);
//假如連接斷開則跳出循環
if (irecv <= 0)
{
delete []buffer;
return 0;
}
psockparam->pListener->AfterReceived(buffer,irecv,strIP.GetBuffer(strIP.GetLength()));
}
//here remove client info from m_pClientList
//if server wanna shut down a socket, it only need to close that socket
POSITION pos;
if (psockparam->pListener->GetClientList()!=NULL)
{
for (pos=psockparam->pListener->GetClientList()->GetHeadPosition();pos!=NULL;)
{
POSITION oldpos=pos;
CLIENTINFO *pInfo=(CLIENTINFO *)psockparam->pListener->GetClientList()->GetNext(pos);
if (pInfo->socket==ClientSocket)
{
psockparam->pListener->GetClientList()->RemoveAt(oldpos);
delete pInfo;
break;
}
}
}
//release resource
delete[] buffer;
closesocket(ClientSocket);
return 0;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CNetCmt::CNetCmt()
{
m_pClientList=new CPtrList();
m_pParam=new SOCKETLISTENPARAM;
m_pClientList=new CPtrList();
m_ListenSocket = INVALID_SOCKET;
m_pShowList = m_pShowClient = NULL;
m_bListening = FALSE;
m_bFrame = FALSE;
m_reccnt = 0;
m_ppAhead = NULL;
m_ppOverlook = NULL;
}
CNetCmt::~CNetCmt()
{
//clear all client information
POSITION pos;
for (pos=m_pClientList->GetHeadPosition();pos!=NULL;)
{
CLIENTINFO *pinfo=(CLIENTINFO *)m_pClientList->GetNext(pos);
closesocket(pinfo->socket);
//delete pinfo;
}
Sleep(500);
for (pos=m_pClientList->GetHeadPosition();pos!=NULL;)
{
CLIENTINFO *pinfo=(CLIENTINFO *)m_pClientList->GetNext(pos);
//closesocket(pinfo->socket);
delete pinfo;
}
m_pClientList->RemoveAll();
delete m_pClientList;
m_pClientList=NULL;
}
BOOL CNetCmt::Listen(int inPort)
{
//初始化
m_nListenPort = inPort;
m_ListenSocket = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in socketaddr;
socketaddr.sin_family = AF_INET;
socketaddr.sin_addr.S_un.S_addr = INADDR_ANY;
socketaddr.sin_port = htons(inPort);
if (bind(m_ListenSocket,(sockaddr *)&socketaddr,sizeof(socketaddr)) != 0)
{
return FALSE;
}
if (listen(m_ListenSocket,300) != 0)
{
return FALSE;
}
//開始監聽
m_pParam->listen_socket = m_ListenSocket;
m_pParam->pListener = this;
AfxBeginThread(ListenThread,m_pParam);
m_bListening = TRUE;
return TRUE;
}
BOOL CNetCmt::Close()
{
closesocket(m_ListenSocket);
m_bListening = FALSE;
return TRUE;
}
BOOL CNetCmt::isListening()
{
return m_bListening;
}
//接收數據以后進行的處理
void CNetCmt::AfterReceived(void *buf, int length,char *pFromIP)
{
for (int i=0;i<=length-7;i++)
{
if (m_Parse((UCHAR*)buf+i,length-i) == TRUE)
{ //解析成功,跳過7個字節
i+=7;
}
}
}
//連接后的處理
void CNetCmt::AferConnect(CLIENTINFO *inClinfo)
{
if (m_pShowClient != NULL)
{
CString ip(inClinfo->fromip);
CString port;
port.Format(": %d",inClinfo->fromport);
ip += port;
m_pShowClient->AddString(ip);
}
memcpy(lastIP,inClinfo->fromip,16);
}
BOOL CNetCmt::GetHostIP(TCHAR * inData)
{
char name[255];
if( gethostname ( name, sizeof(name)) == 0)
{
hostent* pHostent = gethostbyname(name);
hostent& he = *pHostent;
sockaddr_in sa;
for (int nAdapter=0; he.h_addr_list[nAdapter]; nAdapter++)
{
memcpy ( &sa.sin_addr.s_addr, he.h_addr_list[nAdapter],he.h_length);
}
/*inClnt->IP_b1 = (BYTE)sa.sin_addr.S_un.S_un_b.s_b1;
inClnt->IP_b2 = (BYTE)sa.sin_addr.S_un.S_un_b.s_b2;
inClnt->IP_b3 = (BYTE)sa.sin_addr.S_un.S_un_b.s_b3;
inClnt->IP_b4 = (BYTE)sa.sin_addr.S_un.S_un_b.s_b4;*/
}
return TRUE;
}
BOOL CNetCmt::m_Parse(const UCHAR* inbuf,int length)
{
if (inbuf[0] == 0x55 && inbuf[1] == 0xAA)
{
switch(inbuf[2])
{
case 1: //打開
m_pcmd->m_netsend.ConnectTo(lastIP,1000);
m_Control(0);
break;
case 2: //剎車
m_pcmd->SetBehavior(NULL);
m_pcmd->Brake(1);
break;
case 3: //界面按鈕控制
m_Control(inbuf[3]);
break;
case 4: //更新移動速度
SetWindowText(GetDlgItem(m_hmain,IDC_BOTHSPEED),"800");
break;
case 5: //設置動作
break;
case 6: //打開前置攝像頭圖像傳輸
if (m_ppAhead != NULL)
{
if (*m_ppAhead != NULL)
{
(*m_ppAhead)->ConnectTo(lastIP,100038);
}
}
break;
case 7: //關閉前置攝像頭圖像傳輸
if (m_ppAhead != NULL)
{
if (*m_ppAhead != NULL)
{
(*m_ppAhead)->mCB.m_socket = INVALID_SOCKET;
}
}
break;
/* case 8: //打開攝像頭圖像傳輸
if (m_ppAhead != NULL)
{
if (*m_ppAhead != NULL)
{
(*m_ppAhead)->ConnectTo(lastIP,100038);
}
}
break;
case 9: //關閉前置攝像頭圖像傳輸
if (m_ppAhead != NULL)
{
if (*m_ppAhead != NULL)
{
(*m_ppAhead)->mCB.m_socket = INVALID_SOCKET;
}
}
break;*/
}
return TRUE; //合法指令且解析成功
}
else
return FALSE; //非法指令組合
}
void CNetCmt::m_Control(UCHAR inCtrl)
{
HWND h;
switch(inCtrl)
{
case 0: //按下開始按鈕
h = FindWindowEx(m_hmain,0,NULL,"打開");
PostMessage(h,BM_CLICK,0,0);
PostMessage(h,BM_CLICK,0,0);
break;
case 0x01: //按前進
h = FindWindowEx(m_hmain,0,NULL,"前進");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x02: //按后退
h = FindWindowEx(m_hmain,0,NULL,"后退");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x03: //按左轉
h = FindWindowEx(m_hmain,0,NULL,"左轉");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x04: //按右轉
h = FindWindowEx(m_hmain,0,NULL,"右轉");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x05: //按剎車
h = FindWindowEx(m_hmain,0,NULL,"剎車");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x06: //打開前方視頻
h = FindWindowEx(m_hmain,0,NULL,"開啟前方");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x07: //關閉前方視頻
h = FindWindowEx(m_hmain,0,NULL,"關閉前方");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x08: //去行為
h = FindWindowEx(m_hmain,0,NULL,"去除行為");
PostMessage(h,BM_CLICK,0,0);
h = FindWindowEx(m_hmain,0,NULL,"剎車");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x09: //行為一
h = FindWindowEx(m_hmain,0,NULL,"行為一");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x0A: //跟球
h = FindWindowEx(m_hmain,0,NULL,"前向跟球");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x0B: //打開全局視頻
h = FindWindowEx(m_hmain,0,NULL,"開啟全局");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x0C: //關閉全局視頻
h = FindWindowEx(m_hmain,0,NULL,"關閉全局");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x0D: //全局行為
h = FindWindowEx(m_hmain,0,NULL,"全景尋球");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x0E: //打開超聲
h = FindWindowEx(m_hmain,0,NULL,"打開超聲");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x0F: //關閉超聲
h = FindWindowEx(m_hmain,0,NULL,"關閉超聲");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x10: //打開紅外
h = FindWindowEx(m_hmain,0,NULL,"激活紅外");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x11: //關閉紅外
h = FindWindowEx(m_hmain,0,NULL,"關閉紅外");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x12: //打開羅盤
h = FindWindowEx(m_hmain,0,NULL,"激活羅盤");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x13: //關閉羅盤
h = FindWindowEx(m_hmain,0,NULL,"關閉羅盤");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x14: //平滑加速
h = FindWindowEx(m_hmain,0,NULL,"加速");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x15: //三角
h = FindWindowEx(m_hmain,0,NULL,"三角");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x16: //陀螺儀轉向導航
h = FindWindowEx(m_hmain,0,NULL,"轉向");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x17: //陀螺儀直線導航
h = FindWindowEx(m_hmain,0,NULL,"直行");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x18: //S形路線
h = FindWindowEx(m_hmain,0,NULL,"S形");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x19: //踢球
h = FindWindowEx(m_hmain,0,NULL,"踢球");
PostMessage(h,BM_CLICK,0,0);
break;
case 0x1A: //找球
h = FindWindowEx(m_hmain,0,NULL,"前向找球");
PostMessage(h,BM_CLICK,0,0);
break;
}
}
void CNetCmt::SetMainWin(HWND inhwnd)
{
m_hmain = inhwnd;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -