现在的位置: 首页 > 综合 > 正文

自己写远程控制软件之键鼠响应

2013年02月27日 ⁄ 综合 ⁄ 共 1691字 ⁄ 字号 评论关闭

上一篇说图像压缩和显示的时候,大家已经看到了在客户端的捕捉键鼠消息的代码,这里就直接说在服务器的实现了。

代码其实很简单但是需要注意的是,在网络接收消息后,不要在网络回调里,直接 mouse_event或者keybd_event 做其它事情也不行,除了缓冲区取一个缓冲区,然后
Post 到 IOCP 以外,否则,轻则影响效率,重则死锁当然接收的数据还是要处理的,用的是线程池函数
QueueUserWorkItem,你懂的
。不过,
QueueUserWorkItem 有时,有点问题(有时有 .Net 程序运行的时候,CPU 很高,原因不明,可能是要和 .Net 强线程吧),不过,我有仿 QueueUserWorkItem
的函数,可以避免这个问题,这里就不说了

DWORD WINAPI RunCommand(LPVOID lpParam)
{
	SOCKET_POST_CTRL *pRecv = (SOCKET_POST_CTRL *) lpParam;
	switch (pRecv->remoteCtrl.dwCtrl) {
		case CTRL_MOUSE:
			SetCursorPos(pRecv->remoteCtrl.x * GetSystemMetrics(SM_CXSCREEN) / pRecv->remoteCtrl.dwWidth, 
						 pRecv->remoteCtrl.y * GetSystemMetrics(SM_CYSCREEN) / pRecv->remoteCtrl.dwHeight);

			mouse_event(pRecv->remoteCtrl.dwFlags, 0, 0, 0, 0);
			break;
		case CTRL_KEYBOARD:
			::keybd_event((BYTE) pRecv->remoteCtrl.nChar, (BYTE) pRecv->remoteCtrl.nChar, pRecv->remoteCtrl.nFlags, 0);
			break;
		default:
			break;
	}
	SQ_PushBack(pRecv->hQueue, ForceCast<DWORD>(pRecv));
	return 0;
}
VOID OnRecv(SOCKET_POST *pPost)
{
	SOCKET_POST_CTRL *pRecv = (SOCKET_POST_CTRL *) pPost;
	if (pRecv->dwBytesTrans == 0) {
		IOCP_Close(pRecv->pInfo);
		SQ_PushBack(pRecv->hQueue, ForceCast<DWORD>(pRecv));
	}
	else {
		pRecv->dwLeftSize -= pRecv->dwBytesTrans;
		if (pRecv->dwLeftSize > 0) {
			pRecv->pWSABuf		= &(pRecv->wsaBuf[0]);
			pRecv->dwBufCount	= ItemCount(pRecv->wsaBuf);
			pRecv->wsaBuf[0].len= pRecv->dwLeftSize;
			pRecv->wsaBuf[0].buf= (PCHAR) &(pRecv->pktHead);
			pRecv->wsaBuf[0].buf+= (sizeof(pRecv->pktHead) + sizeof(pRecv->remoteCtrl) - pRecv->dwLeftSize);

			IOCP_PostRecv(m_hIOCP, pRecv->pInfo, pRecv);
		}
		else {
			switch (pRecv->pktHead.dwStamp) {
				case STAMP_PACKET:
					QueueUserWorkItem(RunCommand, pRecv, 0);
					SQ_PopFront(m_hQueueRecv, ForceCast<LPDWORD>(&pRecv));
					PostRecv(m_pInfo, pRecv);
					break;
				default:
					IOCP_Close(pRecv->pInfo);
					SQ_PushBack(pRecv->hQueue, ForceCast<DWORD>(pRecv));
					break;
			}
		}
	}
}

抱歉!评论已关闭.