TclientSocket和TserverSocket用法.docx
- 文档编号:10340010
- 上传时间:2023-02-10
- 格式:DOCX
- 页数:23
- 大小:18.21KB
TclientSocket和TserverSocket用法.docx
《TclientSocket和TserverSocket用法.docx》由会员分享,可在线阅读,更多相关《TclientSocket和TserverSocket用法.docx(23页珍藏版)》请在冰豆网上搜索。
TclientSocket和TserverSocket用法
作者:
simitar
笔者在工作中遇到对局域网中各工作站与服务器之间进行Socket通信的问题。
现在将本人总结出来的
TServerSocket和TClientSocket两个组件的基本用法写出来,希望与您分享。
ClientSocket组件为客户端组件。
它是通信的请求方,也就是说,它是主动地与服务器端建立连接。
ServerSocket组件为服务器端组件。
它是通信的响应方,也就是说,它的动作是监听以及被动接受客户端的连接请
求,并对请求进行回复。
ServerSocket组件可以同时接受一个或多个ClientSocket组件的连接请求,并与每个ClientSocket组件建立单独的
连接,进行单独的通信。
因此,一个服务器端可以为多个客户端服务。
设计思路
本例包括一个服务器端程序和一个客户端程序。
客户端程序可以放到多个计算机上运行,同时与服务器端进行连接
通信。
本例的重点,一是演示客户端与服务器端如何通信;二是当有多个客户端同时连接到服务器端时,服务器端如何识
别每个客户端,并对请求给出相应的回复。
为了保证一个客户端断开连接时不影响其它客户端与服务器端的通信,
同时保证服务器端能够正确回复客户端的请求,在本例中声明了一个记录类型:
type
client_record=record
CHandle:
integer;//客户端套接字句柄
CSocket:
TCustomWinSocket;//客户端套接字
CName:
string;//客户端计算机名称
CAddress:
string;//客户端计算机IP地址
CUsed:
boolean;//客户端联机标志
end;
利用这个记录类型数据保存客户端的信息,同时保存当前客户端的连接状态。
其中,CHandle保存客户端套接字句
柄,以便准确定位每个与服务器端保持连接的客户端;Csocket保存客户端套接字,通过它可以对客户端进行回
复。
Cused记录当前客户端是否与服务器端保持连接。
下面对组件ServerSocket和ClientSocket的属性设置简单说明。
ServerSocket的属性:
·Port,是通信的端口,必须设置。
在本例中设置为1025;
·ServerTypt,服务器端读写信息类型,设置为stNonBlocking表示异步读写信息,本例中采用这种方式。
·ThreadCacheSize,客户端的最大连接数,就是服务器端最多允许多少客户端同时连接。
本例采用默认值10。
其它属性采用默认设置即可。
ClientSocket的属性:
·Port,是通信的端口,必须与服务器端的设置相同。
在本例中设置为1025;
·ClientType,客户端读写信息类型,应该与服务器端的设置相同,为stNonBlocking表示异步读写信息。
·Host,客户端要连接的服务器的IP地址。
必须设置,当然也可以在代码中动态设置。
其它属性采用默认设置即可。
程序源代码:
·服务器端源码(uServerMain.pas):
unituServerMain;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,
ScktComp,ToolWin,ComCtrls,ExtCtrls,StdCtrls,Buttons;
const
CMax=10;//客户端最大连接数
type
client_record=record
CHandle:
integer;//客户端套接字句柄
CSocket:
TCustomWinSocket;//客户端套接字
CName:
string;//客户端计算机名称
CAddress:
string;//客户端计算机IP地址
CUsed:
boolean;//客户端联机标志
end;
type
TfrmServerMain=class(TForm)
ServerSocket:
TServerSocket;
ControlBar1:
TControlBar;
ToolBar1:
TToolBar;
tbConnect:
TToolButton;
tbClose:
TToolButton;
tbDisconnected:
TToolButton;
Edit1:
TEdit;
Memo1:
TMemo;
StatusBar:
TStatusBar;
proceduretbConnectClick(Sender:
TObject);
proceduretbDisconnectedClick(Sender:
TObject);
procedureServerSocketClientRead(Sender:
TObject;
Socket:
TCustomWinSocket);
procedureServerSocketListen(Sender:
TObject;
Socket:
TCustomWinSocket);
procedureServerSocketClientConnect(Sender:
TObject;
Socket:
TCustomWinSocket);
procedureServerSocketClientDisconnect(Sender:
TObject;
Socket:
TCustomWinSocket);
proceduretbCloseClick(Sender:
TObject);
procedureFormCreate(Sender:
TObject);
procedureFormClose(Sender:
TObject;varAction:
TCloseAction);
procedureServerSocketGetSocket(Sender:
TObject;Socket:
Integer;
varClientSocket:
TServerClientWinSocket);
procedureServerSocketClientError(Sender:
TObject;
Socket:
TCustomWinSocket;ErrorEvent:
TErrorEvent;
varErrorCode:
Integer);
private
{Privatedeclarations}
public
{Publicdeclarations}
session:
array[0..CMax]ofclient_record;//客户端连接数组
Sessions:
integer;//客户端连接数
end;
var
frmServerMain:
TfrmServerMain;
implementation
{$R*.DFM}
//打开套接字连接,并使套接字进入监听状态
procedureTfrmServerMain.tbConnectClick(Sender:
TObject);
begin
ServerSocket.Open;
end;
//关闭套接字连接,不再监听客户端的请求
procedureTfrmServerMain.tbDisconnectedClick(Sender:
TObject);
begin
ServerSocket.Close;
StatusBar.Panels[0].Text:
=服务器套接字连接已经关闭,无法接受客户端的连接请求.;
end;
//从客户端读取信息
procedureTfrmServerMain.ServerSocketClientRead(Sender:
TObject;
Socket:
TCustomWinSocket);
var
i:
integer;
begin
//将从客户端读取的信息添加到Memo1中
Memo1.Lines.Add(Socket.ReceiveText);
fori:
=0tosessionsdo
begin
//取得匹配的客户端
ifsession[i].CHandle=Socket.SocketHandlethen
begin
session[i].CSocket.SendText(回复客户端+session[i].CAddress+==>+Edit1.Text);
end;
end;
end;
//服务器端套接字进入监听状态,以便监听客户端的连接
procedureTfrmServerMain.ServerSocketListen(Sender:
TObject;
Socket:
TCustomWinSocket);
begin
StatusBar.Panels[0].Text:
=等待客户端连接...;
end;
//当客户端连接到服务器端以后
procedureTfrmServerMain.ServerSocketClientConnect(Sender:
TObject;
Socket:
TCustomWinSocket);
var
i,j:
integer;
begin
j:
=-1;
fori:
=0tosessionsdo
begin
//在原有的客户端连接数组中有中断的客户端连接
ifnotsession[i].CUsedthen
begin
session[i].CHandle:
=Socket.SocketHandle;//客户端套接字句柄
session[i].CSocket:
=Socket;//客户端套接字
session[i].CName:
=Socket.RemoteHost;//客户端计算机名称
session[i].CAddress:
=Socket.RemoteAddress;//客户端计算机IP
session[i].CUsed:
=True;//连接数组当前位置已经占用
Break;
end;
j:
=i;
end;
ifj=sessionsthen
begin
inc(sessions);
session[j].CHandle:
=Socket.SocketHandle;
session[j].CSocket:
=Socket;
session[j].CName:
=Socket.RemoteHost;
session[j].CAddress:
=Socket.RemoteAddress;
session[j].CUsed:
=True;
end;
StatusBar.Panels[0].Text:
=客户端+Socket.RemoteHost+已经连接;
end;
//当客户端断开连接时
procedureTfrmServerMain.ServerSocketClientDisconnect(Sender:
TObject;
Socket:
TCustomWinSocket);
var
i:
integer;
begin
fori:
=0tosessionsdo
begin
ifsession[i].CHandle=Socket.SocketHandlethen
begin
session[i].CHandle:
=0;
session[i].CUsed:
=False;
Break;
end;
end;
StatusBar.Panels[0].Text:
=客户端+Socket.RemoteHost+已经断开;
end;
//关闭窗口
procedureTfrmServerMain.tbCloseClick(Sender:
TObject);
begin
Close;
end;
procedureTfrmServerMain.FormCreate(Sender:
TObject);
begin
sessions:
=0;
end;
procedureTfrmServerMain.FormClose(Sender:
TObject;
varAction:
TCloseAction);
begin
ServerSocket.Close;
end;
//当客户端正在与服务器端连接时
procedureTfrmServerMain.ServerSocketGetSocket(Sender:
TObject;
Socket:
Integer;varClientSocket:
TServerClientWinSocket);
begin
StatusBar.Panels[0].Text:
=客户端正在连接...;
end;
//客户端发生错误
procedureTfrmServerMain.ServerSocketClientError(Sender:
TObject;
Socket:
TCustomWinSocket;ErrorEvent:
TErrorEvent;
varErrorCode:
Integer);
begin
StatusBar.Panels[0].Text:
=客户端+Socket.RemoteHost+发生错误!
;
ErrorCode:
=0;
end;
end.
·客户端源码(uClientMain.pas):
unituClientMain;
interface
uses
Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,
ScktComp,ComCtrls,ToolWin,ExtCtrls,StdCtrls,Buttons;
const
SocketHost=172.16.1.6;//服务器端地址
type
TfrmClientMain=class(TForm)
ControlBar1:
TControlBar;
ToolBar1:
TToolBar;
tbConnected:
TToolButton;
tbSend:
TToolButton;
tbClose:
TToolButton;
tbDisconnected:
TToolButton;
ClientSocket:
TClientSocket;
Edit1:
TEdit;
Memo1:
TMemo;
StatusBar:
TStatusBar;
btnSend:
TBitBtn;
proceduretbConnectedClick(Sender:
TObject);
proceduretbDisconnectedClick(Sender:
TObject);
procedureClientSocketRead(Sender:
TObject;Socket:
TCustomWinSocket);
proceduretbSendClick(Sender:
TObject);
proceduretbCloseClick(Sender:
TObject);
procedureFormShow(Sender:
TObject);
procedureClientSocketConnect(Sender:
TObject;
Socket:
TCustomWinSocket);
procedureClientSocketConnecting(Sender:
TObject;
Socket:
TCustomWinSocket);
procedureClientSocketDisconnect(Sender:
TObject;
Socket:
TCustomWinSocket);
procedureFormClose(Sender:
TObject;varAction:
TCloseAction);
procedureClientSocketError(Sender:
TObject;Socket:
TCustomWinSocket;
ErrorEvent:
TErrorEvent;varErrorCode:
Integer);
private
{Privatedeclarations}
public
{Publicdeclarations}
end;
var
frmClientMain:
TfrmClientMain;
implementation
{$R*.DFM}
//打开套接字连接
procedureTfrmClientMain.tbConnectedClick(Sender:
TObject);
begin
ClientSocket.Open;
end;
//关闭套接字连接
procedureTfrmClientMain.tbDisconnectedClick(Sender:
TObject);
begin
ClientSocket.Close;
end;
//接受服务器端的回复
procedureTfrmClientMain.ClientSocketRead(Sender:
TObject;
Socket:
TCustomWinSocket);
begin
Memo1.Lines.Add(Socket.ReceiveText);
end;
//发送信息到服务器端
procedureTfrmClientMain.tbSendClick(Sender:
TObject);
begin
ClientSocket.Socket.SendText(Edit1.Text);
end;
procedureTfrmClientMain.tbCloseClick(Sender:
TObject);
begin
Close;
end;
//设置要连接的服务器端地址
procedureTfrmClientMain.FormShow(Sender:
TObject);
begin
ClientSocket.Host:
=SocketHost;
end;
//已经连接到服务器端
procedureTfrmClientMain.ClientSocketConnect(Sender:
TObject;
Socket:
TCustomWinSocket);
begin
tbSend.Enabled:
=True;
tbDisconnected.Enabled:
=True;
btnSend.Enabled:
=True;
StatusBar.Panels[0].Text:
=已经连接到+Socket.RemoteHost;
end;
//正在连接到服务器端
procedureTfrmClientMain.ClientSocketConnecting(Sender:
TObject;
Socket:
TCustomWinSocket);
begin
StatusBar.Panels[0].Text:
=正在连接到服务器...;
end;
//当断开与服务器端的连接时发生
procedureTfrmClientMain.ClientSocketDisconnect(Sender:
TObject;
Socket:
TCustomWinSocket);
begin
tbSend.Enabled:
=False;
btnSend.Enabled:
=False;
tbDisconnected.Enabled:
=False;
StatusBar.Panels[0].Text:
=已经断开与+Socket.RemoteHost+的连接;
end;
procedureTfrmClientMain.FormClose(Sender:
TObject;
varAction:
TCloseAction);
begin
ClientSocket.Close;
end;
//当与服务器端的连接发生错误时
procedureTfrmClientMain.ClientSocketError(Sender:
TObject;
Socket:
TCustomWinSocket;ErrorEvent:
TErrorEvent;
varErrorCode:
Integer);
begin
StatusBar.Panels[0].Text:
=与服务器端的连接发生错误;
ErrorCode:
=0;
end;
end.
小结
上述方法是比较简单的实现方法,同时也是相对较容易理解的方法。
通过这个方法,笔者成功实现了局域网内多个
客户端与服务器端进行Socket通信的功能,同时可以保证一个客户端的连接、通信或是断开都不影响其它客户端的
正常通信。
附录:
服务器端窗体和客户端窗体及组件的属性设置参加相应的DFM文件。
uServerMain.pas对应的DFM文件(uServerMain.dfm)
objectfrmServerMain:
TfrmServerMain
Left=297
Top=258
BorderIcons=[biSystemMenu,biMinimize]
BorderStyle=bsSingle
Caption=ServerSocket
ClientHeight=279
ClientWidth=476
Color=clBtnFace
Font.Charset=DEFAULT_CHARSET
Font.Color=clWindowText
Font.Height=-11
Font.Name=MSSansSerif
Font.Style=[]
OldCreateOrder=False
OnClose=FormClose
OnCreate=FormCreate
PixelsPerInch=96
TextHeight=13
objectControlBar1:
TControlBar
Left=0
Top=0
Width=476
Height=30
Align=alTop
AutoSize=True
TabOrder=0
objectToolBar1:
TToolBar
Left=11
Top=2
Width=459
Height=22
ButtonHeight=21
ButtonWidth=55
Caption=ToolBar1
EdgeInner=esNone
EdgeOuter=esNone
Flat=True
ShowCaptions=True
TabOrder=0
objecttbConnect:
TToolButton
Left=0
Top=0
Caption=连接
ImageIndex=0
OnClick=tbConnectClick
end
objecttbDisconnected:
T
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- TclientSocket TserverSocket 用法