⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netcmt.cpp

📁 足球机器人功能demo
💻 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 + -