| 
				 二、远程关机 
远程关机的方法分两种:一种需要在被控制的计算机上编写软件(适用于任何系统)、一种不需要在被控制的计算机上编写软件(只适用于Windows2000、WindowsXP以上任何系统)。   
1.有被控端软件 
需要编写控制端软件和被控端软件,由控制端软件发送自定义的关机命令字符串,被控端软件收到相应命令后关闭本机。通信方式有TCP、UDP两种,TCP是面向连接的,为了保证可靠的传输可采用它,UDP是无连接的,为了提高传输速度可采用它。由于篇幅限制且UDP方式相对简单,我这里只谈TCP方式。 
TCP方式需要通信的一端作为服务端,进行监听(Listen),等待接受(accept)另一端即客户端的连接(connect)。如果仅仅用于关机,将控制端或被控端作为服务端均无不可,但是为了软件的可扩展性,我将控制端作为服务端,关键代码如下: 
(1)服务端: 
先设定服务端地址和端口,创建套接字并绑定,然后将套接字置为监听模式,启动一个线程处理接收。 
sockaddr_in ServerSockAddr; 
ServerSockAddr.sin_addr.s_addr=htonl(INADDR_ANY); 
ServerSockAddr.sin_family=AF_INET; 
ServerSockAddr.sin_port=htons(SERVER_PORT); 
m_SockListen=socket(AF_INET,SOCK_STREAM,0); 
if (bind(m_SockListen,(sockaddr*)&ServerSockAddr,sizeof(ServerSockAddr))) 
        MessageBox("绑定错误"); 
else listen(m_SockListen,5); 
AfxBeginThread(&thread,0); 
在线程函数中接受客户端的连接,得到一个新的套接字,用于和刚接受连接的那个客户机通信。为了使用户能将在ListCtrl控件上所选择的计算机正确关机,需要将ListCtrl控件的行号与该行客户机的连接套接字对应,将与各客户机连接的所有套接字存放在一个套接字数组m_SockClient[]中,因此只要将客户机信息在ListCtrl控件中所在行号作为套接字数组m_SockClient []中的下标来对应该客户机的套接字即可。在accept函数的第二个参数中返回了发出连接请求的那个客户机的I P地址信息,因此只要将该I P地址与ListCtrll控件上所列出的所有客户机的I P地址一一比较,找到该客户机信息所在行号,然后将该客户机的套接字保存在以该行号为下标的数组套接字元素中。关键代码如下: 
UINT thread(LPVOID p) 
{    
SOCKET SockAccept; 
    struct sockaddr_in clientaddr; 
    int iAddrLen=sizeof(struct sockaddr); 
    ULONG ulClientIpAddr; 
    CString strIpAddr; 			
				 |