您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > DELPHI下的SOCK编程
DELPHI下的SOCK编程本文是写给公司新来的程序员的,算是一点培训的教材。本文不会涉及太多的编程细节,只是简单讲解在DELPHI下进行Winsock编程最好了解的知识。题外话:我认为学习编程就如同学习外语一样,最好的方式是你先学会如何去运用它,然后才是了解它的语言特性、语法之类的东西。不过很可惜,我们以前的外语教育使用了相反的过程。软件编程也是一样,在很多人的大学阶段,你更多的是学习那些理论知识,学习“语法”,这里,我丝毫没有贬低理论知识重要性的意思。理论知识和实践是相辅相成的,但一个恰当的学习方式,很多时候可以让学习者得到事半功倍的效果。例如你学习《数据结构》中排序的概念,我们假设对此概念你学习的非常出色,你脑子中有大量关于不同排序方法优劣的思想,你也自己琢摸出了很多奇妙的构思,但你没有丝毫编写代码的基本功,你所有一切的niceidea都只能停留在你的脑子中,你甚至不知道在实践运用中,这些idea是否可行,实践是检验真理的唯一标准。倘若你先具备了一些可以用于实践的基本技能,再去学习那些概念,我想,你可以很好的将”冒泡排序“实现出来,然后在这种实现和理论的结合中不断的前行。本文会从DELPHI7中的TServerSocket等组件出发,边用边学,直到API以及那些所谓的”思想“。“当你相信并不理解的东西时,你就会受罪了。迷信不是办法”。--SteviceWonderRAD使得程序的编制更方便和快捷,即使没有经受专业的训练,依然可以写出完成一些功能的程序,在我现在的公司内部,有时候我会问公司的新员工,你为什么这样写,你的代码是怎么运行的?“不知道,反正可以运行。”我认为对于准备在Win32开发领域做下去的程序员来说,这是悲哀的。前面已经说了,本文最终的目的不是简单的组件使用,而是让读者可以了解到Winsock的API以及DELPHI7中TServerSocket等VCL组件的编写。我始终认为对于一名合格的win32程序员来说,无论你使用什么工具编写代码,你都应该深入底层,起码你应该了解WinAPI,否则的话,在面对那些组件错误的时候,你只能莫名其妙的扣着脑袋,在编程的道路上,最多也只能成为一名熟练的”搬运工“。阅读本文,你起码应该具备对ObjectPascal的了解,如果能有一点UML的知识就更好了,因为文中会包含一些这方面的图形。WINSOCK的基本概念在Win32平台下进程网络编程,对于众多的基层网络协议,Winsock是访问它们的首选接口。而且在每个Win32平台上,Winsock都以不同的形式存在着。要说明的是,Winsock是网络编程接口,而不是协议。它从Unix平台的Berkeley(BSD)套接字方案借鉴了许多东西,后者能访问多种网络协议。在Win32环境中,Winsock接口最终成为一个真正的“与协议无关”接口,尤其是在Winsock2发布之后。Winsock的API是建立在套接字基础上的。所谓套接字,就是一个指向传输提供者的句柄。Win32中,套接字不同于文件描述符,所以它是一个独立的类型—SOCKET。第一个程序在了解那些组件和API之前,我们先来使用一下。下面的程序非常的简单,只是一个在服务器和客户机之间建立连接并通讯的程序。如果你已经使用TServerSocket以及TClientSocket做过客户端服务器的通讯程序,那么下面的内容你完全可以跳过。我们使用TServerSocket组件来建立服务器端的程序。它包含两个memo组件,用来分别处理接收到的数据和发送的数据,然后再在窗体上方一个TServerSocket组件,ServerType设置为stNonBlocking,Port设置为100,active设置为true,写几句简单的代码如下:unitUnit1;interfaceusesWindows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,ComCtrls,StdCtrls,ScktComp;typeTForm1=class(TForm)ServerSocket1:TServerSocket;Memo1:TMemo;Button1:TButton;StatusBar1:TStatusBar;Memo2:TMemo;procedureServerSocket1ClientConnect(Sender:TObject;Socket:TCustomWinSocket);procedureServerSocket1ClientDisconnect(Sender:TObject;Socket:TCustomWinSocket);procedureServerSocket1ClientRead(Sender:TObject;Socket:TCustomWinSocket);procedureButton1Click(Sender:TObject);private...{Privatedeclarations}public...{Publicdeclarations}end;varForm1:TForm1;implementation...{$R*.dfm}procedureTForm1.ServerSocket1ClientConnect(Sender:TObject;Socket:TCustomWinSocket);beginStatusBar1.SimpleText:='connect';end;procedureTForm1.ServerSocket1ClientDisconnect(Sender:TObject;Socket:TCustomWinSocket);beginStatusBar1.SimpleText:='disconnect';end;procedureTForm1.ServerSocket1ClientRead(Sender:TObject;Socket:TCustomWinSocket);beginMemo1.Lines.Add(Socket.ReceiveText);end;procedureTForm1.Button1Click(Sender:TObject);beginifServerSocket1.ActivethenServerSocket1.Socket.Connections[0].SendText(Memo2.Text);end;end.然后编译程序。客户端实现:客户端相对复杂一些,因为我们要有一个用来接收服务器IP地址的edit,以及端口地址的edit。unitUnit1;interfaceusesWindows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,ComCtrls,StdCtrls,ScktComp;typeTForm1=class(TForm)ClientSocket1:TClientSocket;edIp:TEdit;Label1:TLabel;Label2:TLabel;edPort:TEdit;StatusBar1:TStatusBar;Memo1:TMemo;btnConnect:TButton;btnSent:TButton;btnDisconnect:TButton;Memo2:TMemo;procedureClientSocket1Connect(Sender:TObject;Socket:TCustomWinSocket);procedurebtnConnectClick(Sender:TObject);procedurebtnDisconnectClick(Sender:TObject);procedurebtnSentClick(Sender:TObject);procedureClientSocket1Read(Sender:TObject;Socket:TCustomWinSocket);private...{Privatedeclarations}public...{Publicdeclarations}end;varForm1:TForm1;implementation...{$R*.dfm}procedureTForm1.ClientSocket1Connect(Sender:TObject;Socket:TCustomWinSocket);beginStatusBar1.SimpleText:='连接成功';end;procedureTForm1.btnConnectClick(Sender:TObject);beginifnotClientSocket1.ActivethenbeginClientSocket1.Host:=edIp.Text;ClientSocket1.Port:=StrToInt(edPort.Text);ClientSocket1.Open;(SenderasTButton).Enabled:=false;btnDisconnect.Enabled:=true;end;end;procedureTForm1.btnDisconnectClick(Sender:TObject);beginifClientSocket1.ActivethenbeginClientSocket1.Close;btnDisconnect.Enabled:=false;btnConnect.Enabled:=true;end;end;procedureTForm1.btnSentClick(Sender:TObject);beginifClientSocket1.ActivethenClientSocket1.Socket.SendText(Memo1.Text)end;procedureTForm1.ClientSocket1Read(Sender:TObject;Socket:TCustomWinSocket);beginMemo2.Lines.Add(Socket.ReceiveText);end;end.上面的代码非常简单,我甚至不想对它添加任何评述,只所以放上去这个例子,只是想让那些对sock没有任何概念的读者先有一个简单的了解。是的,我们可以使用Winsock来编程一个网络会话程序。去看看源码前面说过,本文的目的不是告诉你如何使用DELPHI中这些用于winsock编程的组件,我们的目的是WinsockApi。那么我们现在就去看看TClientSocket以及TServerSocket的源码。他们在ScktComp.pas单元中被实现,OK,我们看到了此单元中定义的一些类,其中自然包含TClientSocket以及TServerSocket,看看他们的继承关系,下面的一幅UML类图我想可以反映一些信息。图中,我划分了一些区域,并对他们上色,这并不是UML的部分,只所以这样,是为了方便我这里的描绘。从ScktComp类图中,我们看到了5块区域,从蓝色的4号区域,我们可以看到TClientSocket以及TServerSocket的继承关系,是的,你看到了TComponent,也就是说,TClientSocket以及TServerSocket是一个组件,他们的目的是让我们可以建立典型的客户机/服务器模式的通讯程序,从设计的概念上说,他们并不负责通讯的具体处理,仔细观察他们的代码,你会发现二者有一个共同的地方,就是都有一个T***WinSocket的私有变量,是的,T***WinSocket才是真正完成对WinSockAPI封装的地方。勿在浅沙筑高楼。在谈论TServerSocket等组件编写之前,这里先对Winsock中一些基本概念和API函数做一个简单的说明。一、定址要通过Winsock建立通信,必须了解如何利用指定的协议为工作站定址。Winsock2引入了几个新的、与协议无关的函数,它们可和任何一个地址家族一起使用
本文标题:DELPHI下的SOCK编程
链接地址:https://www.777doc.com/doc-5527126 .html