中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 操作系统 > SCO_Unix
[转贴]用Delphi在客户端执行Unix主机命令
作者:未知 时间:2005-09-13 15:08 出处:ChinaUnix.net 责编:chinaitpower
              摘要:[转贴]用Delphi在客户端执行Unix主机命令

[code:1:779cf827c6]

南京市检察院技术处 方源  

问题的提出 
在一个客户/服务器模式的网络环境中,数据库(Informix)服务器建立在SCO Unix 5.05上,同时,有若干台运行Windows 95/98的工作站。需要解决的问题是:如何在客户端执行一段程序,然后由服务器来完成数据库中数据的处理并进行转发,即由客户端来控制远端服务器的命令执行。它的实际意义在于服务器可能位于几公里甚至几百公里以外的地方。 
解决的方法和思路 
由于SCO Unix服务器提供了多种网络服务,如WWW、FTP、MAIL、GOPHER、TELNET等,我们可以在客户端通过TELNET访问远端主机,登录成功后,由服务器直接执行来自客户端的命令集,从而实现对服务器上的数据进行处理的目的。 
本文客户端开发语言选择Delphi,当然,VC++也是此类编程的利器,尤其是VC++对WINSOCK的封装极大地减轻了程序员的工作量,可以说在Windows 95/98平台上它是网络软件开发的最佳选择。而Delphi最大的长处则在于对数据库的支持能力上,同时,它的组件也非常丰富。  
众所周知,TCP/IP协议是Internet上的标准协议集,也是目前网络操作系统所支持的主要协议之一。TELNET实际上是TCP/IP的应用层协议,属于高层协议之一,这个协议提供了一个相对一般的、双向的通信服务。TELNET连接实际上就是一个TCP连接,一旦这种连接建立成功,那么,用户的计算机将作为远端主机的终端来使用而不管主机的物理位置是在同一间办公室内,或是千里之外。TELNET协议除了人们通常所知道的网络虚拟终端外,还有另外一个重要的概念:协商任选项机制。这种机制允许服务器和客户程序之间协商选项,TELNET的某些任选项是已经分配好的(如表1所示)。 
任选项 意义 
0 二进制传送 
1 回送 
2 GO AHEAD 
3 AMS协商 
5 状态 
6 时标 
7 远程受控传送 
8 输出行结束 
9 输出页大小 
10 输出回车描述 
24 终端类型 
…… …… 
表1 
本文对任选项做了如下定义:  
  const F_IAC=255; 
  DO协商 
  const F_DO=253; 
  DO NOT协商 
  const F_DONT=254; 
  WILL 协商 
  const F_WILL=251; 
  WILL NOT协商 
  const F_WONT=252; 
  const F_GOAHEAD=3; 
  const F_ECHO=1; 
编程实现 
为了能将解决问题的方法说得更清楚,本文对实现功能进行了简化,即客户程序登录主机之后,由Unix主机执行一个来自客户端的命令:MKDIR /TMP/FANG。命令执行完后,可以在服务器上查看执行结果。当然,在实际编程环境下不会仅仅是这样一条简单的命令,但基本原理是相同的。程序的测试界面如图1所示: 
  




图1 测试界面 


在Form1中有一个非可视组件TClientSocket,它位于组件面板的Internet页上。Delphi利用这个组件对TCP/IP进行了封装。 
程序的部分代码如下: 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
 if ClientSocket1.Active then ClientSocket1.Active := False; 
  if InputQuery(‘连接至:', ‘地址:', Server) then 
   if Length(Server) > 0 then 
    with ClientSocket1 do 
    begin 
     Address := Server; 
     Active := True; 
end; 
end; 
procedure TForm1.readfromhost(Sender:TObject;  
Socket: TCustomWinSocket); 
begin 
 loginsend:=False; 
 passsend:=False; 
 count:=Socket.ReceiveBuf(InBuffer,High 
(InBuffer)); 
 m_count:=0; 
 while (m_count<count) do 
begin 
ch:=InBuffer[m_count]; 
if (ch=char(F_IAC)) then 
begin 
m_count:=m_count+1; 
cmd:=InBuffer[m_count]; 
   if((cmd=char(F_DO))or(cmd=char 
(F_WILL))or(cmd=char(F_DONT))or(cmd=char 
(F_WONT))) then 
begin 
m_count:=m_count+1; 
nOpt:=InBuffer[m_count]; 
if((nOpt=char(F_GOAHEAD))or 
(nOpt=char(F_ECHO))) then 
begin 
if(cmd=char(F_DO)) then 
begin 
reply[0]:=char(F_IAC); 
reply[1]:=char(F_WILL); 
reply[2]:=nOpt; 
Socket.SendBuf(reply,Length(reply)); 
end; 
if(cmd=char(F_WILL)) then 
  begin 
reply[0]:=char(F_IAC); 
reply[1]:=char(F_DO); 
reply[2]:=nOpt; 
Socket.SendBuf(reply, 
Length(reply)); 
end; 
end; 
if((nOpt<>char(F_GOAHEAD))or(nOpt<>char(F_ECHO))) then 
begin 
if(cmd=char(F_DO)) then 
begin 
reply[0]:=char(F_IAC); 
reply[1]:=char(F_WONT); 
reply[2]:=nOpt; 
Socket.SendBuf(reply, 
Length(reply)); 
end; 
if(cmd=char(F_WILL)) then 
begin 
reply[0]:=char(F_IAC); 
reply[1]:=char(F_DONT); 
reply[2]:=nOpt; 
Socket.SendBuf(reply, 
Length(reply)); 
end; 
end; 
end; 
end; //end F_IAC 
if(ch<>char(F_IAC)) then 
begin 
m_string:=m_string+ch; 
end; 
m_count:=m_count+1; 
  end;  
  //假设编程者知道Unix的LOGIN和PASSWORD 
  if(Length(m_string)>0) then 
   begin 
while ((Pos(‘login:',m_string)>0)and(not  
loginsend)) do 
begin 
cmdtounix:=‘root'+#10+#13; 
code:=Socket.SendBuf(cmdtounix,6); 
loginsend:=True; 
end; 
while ((Pos(‘Password:',m_string)>0)and(not passsend)) do 
begin 
cmdtounix:=‘root'+#13+#10; 
code:=Socket.SendBuf(cmdtounix,6); 
passsend:=True; 
m_string:=‘'; 
end; 
if ( Pos(‘jcy:/#>',m_string)>0) then 
begin 
cmdtounix:=‘mkdir /tmp/fang'+# 
13+#10; 
code:=Socket.SendBuf(cmdtounix, 
Length(cmdtounix)); 
if code>0 then 
begin 
ClientSocket1.Active:=False; 
Close; 
end; 
end; 
   end; 
  end;  
end; 
小 结 
 
虽然这段程序并不复杂,但它是网络软件编程的一个基本思路。需要指出的是,在某些场合,程序员也可以根据自己的需要定义一些协议,以便解决问题。当然,自己定义的协议应用范围可能会很窄,只能在某个系统或程序中使用。 
[/code:1:779cf827c6][/code]



图1 测试界面


关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有