📄 socket编程.htm
字号:
<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>SOCKET 编程</title>
</head>
<body>
<p align="center"><b>SOCKET 编程</b></p>
<table border="1" width="100%" bgcolor="#C0C0C0">
<tr>
<td width="100%">ClientSocket组件为客户端组件。它是通信的请求方,也就是说,它是主动地与服务器端建立连接。ServerSocket组件为服务器端组件。它是通信的响应方,也就是说,它的动作是监听以及被动接受客户端的连接请求,并对请求进行回复。
ServerSocket组件可以同时接受一个或多个ClientSocket组件的连接请求,并与每个ClientSocket组件建立单独的连接,进行单独的通信。因此,一个服务器端可以为多个客户端服务。<br>
<br>
设计思路<br>
本例包括一个服务器端程序和一个客户端程序。客户端程序可以放到多个计算机上运行,同时与服务器端进行连接通信。<br>
本例的重点,一是演示客户端与服务器端如何通信;二是当有多个客户端同时连接到服务器端时,服务器端如何识别每个客户端,并对请求给出相应的回复。为了保证一个客户端断开连接时不影响其它客户端与服务器端的通信,同时保证服务器端能够正确回复客户端的请求,在本例中声明了一个记录类型:<br>
<div align="center">
<table borderColor="#d0a070" cellSpacing="0" borderColorDark="#ffffff" cellPadding="5" width="99%" bgColor="#ffffc0" border="1">
<tbody>
<tr>
<td><code><br>
<font color="#000000"><b>type</b></font><br>
client_<font color="#000000"><b>record</b></font>=<font color="#000000"><b>record</b></font><br>
CHandle: integer; <font color="#770000"><i>//客户端套接字句柄<br>
</i></font><font color="#770000"><i> </i></font>CSocket:TCustomWinSocket;
<font color="#770000"><i>//客户端套接字<br>
</i></font><font color="#770000"><i> </i></font>CName:<font color="#000000"><b>string</b></font>;
<font color="#770000"><i>//客户端计算机名称<br>
</i></font><font color="#770000"><i> </i></font>CAddress:<font color="#000000"><b>string</b></font>;
<font color="#770000"><i>//客户端计算机IP地址<br>
</i></font><font color="#770000"><i> </i></font>CUsed:
boolean; <font color="#770000"><i>//客户端联机标志<br>
</i></font><font color="#000000"><b>end</b></font>;</code></td>
</tr>
</tbody>
</table>
</div>
<br>
利用这个记录类型数据保存客户端的信息,同时保存当前客户端的连接状态。其中,CHandle保存客户端套接字句柄,以便准确定位每个与服务器端保持连接的客户端;Csocket保存客户端套接字,通过它可以对客户端进行回复。Cused记录当前客户端是否与服务器端保持连接。<br>
下面对组件ServerSocket和ClientSocket的属性设置简单说明。<br>
<br>
<div align="center">
<table borderColor="#d0a070" cellSpacing="0" borderColorDark="#ffffff" cellPadding="5" width="99%" bgColor="#ffffc0" border="1">
<tbody>
<tr>
<td><code><br>
ServerSocket的属性:<br>
· Port,是通信的端口,必须设置。在本例中设置为1025;<br>
· ServerTypt,服务器端读写信息类型,设置为stNonBlocking表示异步读写信息,本例中采用这种方式。<br>
· ThreadCacheSize,客户端的最大连接数,就是服务器端最多允许多少客户端同时连接。本例采用默认值10。<br>
其它属性采用默认设置即可。<br>
ClientSocket的属性:<br>
· Port,是通信的端口,必须与服务器端的设置相同。在本例中设置为1025;<br>
· ClientType,客户端读写信息类型,应该与服务器端的设置相同,为stNonBlocking表示异步读写信息。<br>
· Host,客户端要连接的服务器的IP地址。必须设置,当然也可以在代码中动态设置。<br>
其它属性采用默认设置即可。<br>
</code></td>
</tr>
</tbody>
</table>
</div>
<br>
程序源代码:<br>
· 服务器端源码(uServerMain.pas):<br>
<div align="center">
<table borderColor="#d0a070" cellSpacing="0" borderColorDark="#ffffff" cellPadding="5" width="99%" bgColor="#ffffc0" border="1">
<tbody>
<tr>
<td><code><br>
<font color="#000000"><b>unit</b></font> uServerMain;<br>
<font color="#000000"><b>interface</b></font><br>
<font color="#000000"><b>uses</b></font><br>
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,<br>
ScktComp, ToolWin, ComCtrls, ExtCtrls, StdCtrls, Buttons;<br>
<font color="#000000"><b>const</b></font><br>
CMax=10; <font color="#770000"><i>//客户端最大连接数<br>
</i></font><font color="#000000"><b>type</b></font><br>
client_<font color="#000000"><b>record</b></font>=<font color="#000000"><b>record</b></font><br>
CHandle: integer; <font color="#770000"><i>//客户端套接字句柄<br>
</i></font>CSocket:TCustomWinSocket; <font color="#770000"><i>//客户端套接字<br>
</i></font>CName:<font color="#000000"><b>string</b></font>; <font color="#770000"><i>//客户端计算机名称<br>
</i></font>CAddress:<font color="#000000"><b>string</b></font>; <font color="#770000"><i>//客户端计算机IP地址<br>
</i></font>CUsed: boolean; <font color="#770000"><i>//客户端联机标志<br>
</i></font><font color="#000000"><b>end</b></font>;<br>
<font color="#000000"><b>type</b></font><br>
TfrmServerMain = <font color="#000000"><b>class</b></font>(TForm)<br>
ServerSocket: TServerSocket;<br>
ControlBar1: TControlBar;<br>
ToolBar1: TToolBar;<br>
tbConnect: TToolButton;<br>
tbClose: TToolButton;<br>
tbDisconnected: TToolButton;<br>
Edit1: TEdit;<br>
Memo1: TMemo;<br>
StatusBar: TStatusBar;<br>
<font color="#000000"><b>procedure</b></font>
tbConnectClick(Sender: TObject);<br>
<font color="#000000"><b>procedure</b></font>
tbDisconnectedClick(Sender: TObject);<br>
<font color="#000000"><b>procedure</b></font>
ServerSocketClientRead(Sender: TObject;<br>
Socket: TCustomWinSocket);<br>
<font color="#000000"><b>procedure</b></font>
ServerSocketListen(Sender: TObject;<br>
Socket: TCustomWinSocket);<br>
<font color="#000000"><b>procedure</b></font>
ServerSocketClientConnect(Sender: TObject;<br>
Socket: TCustomWinSocket);<br>
<font color="#000000"><b>procedure</b></font>
ServerSocketClientDisconnect(Sender: TObject;<br>
Socket: TCustomWinSocket);<br>
<font color="#000000"><b>procedure</b></font>
tbCloseClick(Sender: TObject);<br>
<font color="#000000"><b>procedure</b></font> FormCreate(Sender:
TObject);<br>
<font color="#000000"><b>procedure</b></font> FormClose(Sender:
TObject; <font color="#000000"><b>var</b></font> Action:
TCloseAction);<br>
<font color="#000000"><b>procedure</b></font>
ServerSocketGetSocket(Sender: TObject; Socket: Integer;<br>
<font color="#000000"><b>var</b></font> ClientSocket:
TServerClientWinSocket);<br>
<font color="#000000"><b>procedure</b></font>
ServerSocketClientError(Sender: TObject;<br>
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;<br>
<font color="#000000"><b>var</b></font> ErrorCode: Integer);<br>
<font color="#000000"><b>private</b></font><br>
<font color="#770000"><i>{ Private declarations }</i></font><br>
<font color="#000000"><b>public</b></font><br>
<font color="#770000"><i>{ Public declarations }</i></font><br>
session: <font color="#000000"><b>array</b></font>[0..CMax] <font color="#000000"><b>of</b></font>
client_<font color="#000000"><b>record</b></font>; <font color="#770000"><i>//客户端连接数组<br>
</i></font>Sessions: integer; <font color="#770000"><i>//客户端连接数<br>
</i></font><font color="#000000"><b>end</b></font>;<br>
<font color="#000000"><b>var</b></font><br>
frmServerMain: TfrmServerMain;<br>
<font color="#000000"><b>implementation</b></font><br>
<font color="#770000"><i>{$R *.DFM}</i></font><br>
<font color="#770000"><i>//打开套接字连接,并使套接字进入监听状态<br>
</i></font><font color="#000000"><b>procedure</b></font>
TfrmServerMain.tbConnectClick(Sender: TObject);<br>
<font color="#000000"><b>begin</b></font><br>
ServerSocket.Open ;<br>
<font color="#000000"><b>end</b></font>;<br>
<font color="#770000"><i>//关闭套接字连接,不再监听客户端的请求<br>
</i></font><font color="#000000"><b>procedure</b></font>
TfrmServerMain.tbDisconnectedClick(Sender: TObject);<br>
<font color="#000000"><b>begin</b></font><br>
ServerSocket.Close;<br>
StatusBar.Panels[0].Text :='服务器套接字连接已经关闭,无法接受客户端的连接请求.';<br>
<font color="#000000"><b>end</b></font>;<br>
<font color="#770000"><i>//从客户端读取信息<br>
</i></font><font color="#000000"><b>procedure</b></font>
TfrmServerMain.ServerSocketClientRead(Sender: TObject;<br>
Socket: TCustomWinSocket);<br>
<font color="#000000"><b>var</b></font><br>
i:integer;<br>
<font color="#000000"><b>begin</b></font><br>
<font color="#770000"><i>//将从客户端读取的信息添加到Memo1中<br>
</i></font>Memo1.Lines.Add(Socket.ReceiveText);<br>
<font color="#000000"><b>for</b></font> i:=0 <font color="#000000"><b>to</b></font>
sessions <font color="#000000"><b>do</b></font><br>
<font color="#000000"><b>begin</b></font><br>
<font color="#770000"><i>//取得匹配的客户端<br>
</i></font><font color="#000000"><b>if</b></font>
session[i].CHandle = Socket.SocketHandle <font color="#000000"><b>then</b></font><br>
<font color="#000000"><b>begin</b></font><br>
session[i].CSocket.SendText('回复客户端'+session[i].CAddress+'
==> '+Edit1.Text);<br>
<font color="#000000"><b>end</b></font>;<br>
<font color="#000000"><b>end</b></font>;<br>
<font color="#000000"><b>end</b></font>;<br>
<font color="#770000"><i>//服务器端套接字进入监听状态,以便监听客户端的连接<br>
</i></font><font color="#000000"><b>procedure</b></font>
TfrmServerMain.ServerSocketListen(Sender: TObject;<br>
Socket: TCustomWinSocket);<br>
<font color="#000000"><b>begin</b></font><br>
StatusBar.Panels[0].Text :='等待客户端连接...';<br>
<font color="#000000"><b>end</b></font>;<br>
<font color="#770000"><i>//当客户端连接到服务器端以后<br>
</i></font><font color="#000000"><b>procedure</b></font>
TfrmServerMain.ServerSocketClientConnect(Sender: TObject;<br>
Socket: TCustomWinSocket);<br>
<font color="#000000"><b>var</b></font><br>
i,j:integer;<br>
<font color="#000000"><b>begin</b></font><br>
j:=-1;<br>
<font color="#000000"><b>for</b></font> i:=0 <font color="#000000"><b>to</b></font>
sessions <font color="#000000"><b>do</b></font><br>
<font color="#000000"><b>begin</b></font><br>
<font color="#770000"><i>//在原有的客户端连接数组中有中断的客户端连接<br>
</i></font><font color="#000000"><b>if</b></font> <font color="#000000"><b>not</b></font>
session[i].CUsed <font color="#000000"><b>then</b></font><br>
<font color="#000000"><b>begin</b></font><br>
session[i].CHandle :=
Socket.SocketHandle ;<font color="#770000"><i>//客户端套接字句柄<br>
</i></font>session[i].CSocket := Socket; <font color="#770000"><i>//客户端套接字<br>
</i></font>session[i].CName := Socket.RemoteHost ; <font color="#770000"><i>//客户端计算机名称<br>
</i></font>session[i].CAddress := Socket.RemoteAddress ;<font color="#770000"><i>//客户端计算机IP<br>
</i></font>session[i].CUsed := <font color="#000000"><b>True</b></font>;
<font color="#770000"><i>//连接数组当前位置已经占用<br>
</i></font>Break;<br>
<font color="#000000"><b>end</b></font>;<br>
j:=i;<br>
<font color="#000000"><b>end</b></font>;<br>
<font color="#000000"><b>if</b></font> j=sessions <font color="#000000"><b>then</b></font><br>
<font color="#000000"><b>begin</b></font><br>
inc(sessions);<br>
session[j].CHandle :=
Socket.SocketHandle ;<br>
session[j].CSocket := Socket;<br>
session[j].CName := Socket.RemoteHost ;<br>
session[j].CAddress :=
Socket.RemoteAddress ;<br>
session[j].CUsed := <font color="#000000"><b>True</b></font>;<br>
<font color="#000000"><b>end</b></font>;<br>
StatusBar.Panels[0].Text := '客户端
'+Socket.RemoteHost + ' 已经连接';<br>
<font color="#000000"><b>end</b></font>;<br>
<font color="#770000"><i>//当客户端断开连接时<br>
</i></font><font color="#000000"><b>procedure</b></font>
TfrmServerMain.ServerSocketClientDisconnect(Sender: TObject;<br>
Socket: TCustomWinSocket);<br>
<font color="#000000"><b>var</b></font><br>
i:integer;<br>
<font color="#000000"><b>begin</b></font><br>
<font color="#000000"><b>for</b></font> i:=0 <font color="#000000"><b>to</b></font>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -