文档库 最新最全的文档下载
当前位置:文档库 › TServerSocket和TClientSocket的使用

TServerSocket和TClientSocket的使用

TServerSocket和TClientSocket的使用

关键字:TServerSocket,TClientSocket

作者:佚名更新:2003-3-9 浏览:18820

在网络编程中,WinSocket API编程是最基本,也是最麻烦的地方(说句不怕影响形象的话,我对此就是一知半解)。但是,如果你是使用C++Builder作为编程平台,你就偷着乐吧,有了BCB,菜鸟变高手!:-)

在BCB中,TServerSocket和TClientSocket涵盖了基本的WinSocket编程,其中TServerSocket 作为服务器方使用,TClientSocket作为客户端使用,这两个组件本身并不提供Socket连接,但是他们都有一个Socket属性,这个属性才提供了Socket连接。下面就先向大家介绍一下这两个组件常用的方法属性,然后在通过一个例子来看看这两个组件的使用。

1)TServerSocket

名称类型说明

Socket TServerWinSocket 最重要的属性,提供Socket连接,事实上发送/接收数据都要靠这个属性.

Port int 要监听的端口,如果在Service属性中指定了服务类型,此属性将被忽略. Service AnsiString 提供的服务,如HTTP、FTP等,如果在这里指定了服务类型,

Port将被忽略,因为各种服务都有特定的端口,如FTP:21、HTTP:80 ServerType TServerType 设置与客户连接的方式,取值为两个枚举常量stNonBlocking和 stThreadBlocking,stNonBlocking表示用非阻塞方式连接每一个客户

每个连接都在一个单独的线程中处理。并用OnClientRead()和

OnClientWrite()通知服务器端的Socker进行读写。stThreadBlocking

表示以阻塞方式连接客户,即以主动查询的方式可客户连接。

Active bool 激活服务,相当于调用Open()方法。

OnAccept事件当有客户请求连接时触发

OnClientRead事件通知服务器去读取有关信息。OnClientWrite与此类似。

2)TClientSocket

名称类型说明

Socket TClientWinSocket 同TServerSocket

Active bool 同TServerSocket

Address AnsiString 服务器的IP地址,如202.98.35.14

ClientType TClientType 与服务器连接方式,取值为两个枚举常量ctNonBlocking,tBlocking。

ctNonBlocking表示非阻塞方式,ctBlocking表示阻塞方式,详见上例。Host AnsiString 要连接的主机名,如https://www.wendangku.net/doc/5617875613.html,

Port int 同TServerSocket

Service AnsiString 同TServerSocket

OnConnect事件当连接时发生,OnConnecting、OnDisConnect与此类似

OnRead事件通知客户机去读取有关信息。OnWrite与此类似。

TServerSocket和TClientSocket只提供基本的服务器/客户机的连接,真正提供数据传输的是它们都有的属性Socket,它的类型分别是TServerWinSocket和TClientWinSocket,而TServerWinSocket和TClientWinSocket的父类都是TCustomWinSocket,下面我们就来看看TServerWinSocket和TClientWinSocket常用的属性和方法。

共同的属性方法(来源于TCustomWinSocket)

名称类型说明

Connected bool 检查是否连接成功

LocalAddress AnsiString 本地IP地址,与此类似LocalHost:本机域名,LocalPort:本机端口

RemoteAddress AnsiString 另一端的IP地址,与此类似RemoteHost:另一端域名,

RemotePort:另一端端口

SocketHandle int 只读,返回Socket对象的Windows句柄,调用WinSocket API函数会用到它。

Handle HWND Socket能够接受到的异步事件都是以Windows消息的形式发送给此句柄的。

Close()方法作为服务器,关闭所有连接;作为客户机,关闭自己与服务器的连接

SendText(AnsiString)方法发送一个字符串,

SendBuf(void* buff,int count)发送缓冲区buff中的count个字节,返回实际发送的字节数SendStream(TStream* AStream)发送一个流到Socket中。

ReceiveText()从Socket中读取并返回一个字符串。

ReceiveLength()从Socket读取数据需多少字节的缓冲区。

ReceiveBuf(void* buff,int count)从Socket中读取count字节的数据到buff。

TClientWinSocket

TClientWinSocket只增加了一个ClientType属性,

用于决定与服务器的连接类型(参见TClientSocket->ClientType)。

TServerWinSocket

名称类型说明

ServerType 服务类型,参见TServerSocket->ServerType。

ActiveConnection int只读,返回当前活动的连接数。

Connection TCustomWinSocket数组,索引n表示第n+1个连接,如Connection[0]表示第一个连接。

有了这些知识,我们就可以完成一些基本的WinSocket编程了,下面就结合一个简单的闲聊程序来看看具体的应用。

首先在窗体上放置以下VCL组件,并修改相应属性:

类型 Name 属性 Caption/Text 说明

本文转自研究w w w m&m w

CheckBox ckListen 监听当选取时,本程序作为服务器

TCheckBox ckConnect 连接当选取时,本程序作为客户机

TEdit edName 无名氏闲聊时所用的名字。

TBitBtn bbtSave&S 保存单击时保存谈话内容

TBitBtn bbtClose&C 关闭单击时关闭此窗口(设置Kind=bkClose)

TEdit edTalk 在此输入谈话内容

TMemo mmTalk 在此显示谈话内容

TServerSocket ServerSocket1作服务器时使用(设置Port=2222)

TClientSocket ClientSocket1作为客户时使用(设置Port=2222)

TSaveDialog sdTalk保存文件时的选项(设置DefaultExt="*.txt",Filter=文本文件(*.TXT)

|*.txt|所有文件(*.*)|*.*)。

TStatusBar StatusBar1 用于显示一些提示信息,只要在属性"Pannels"中加一栏即可

程序作为服务器的设置:

当单击"监听"时,如果没有监听则开始监听,在提示栏中显示"监听",并把"连接"这个复选框无效。如果已经监听,则取消监听,并使"连接"这个复选框有效。所以,在ckListen的OnClick事件中加入以下代码:

if(ServerSocket1->Active)

{

ServerSocket1->Active=false;

ckListen->Checked=false;

StatusBar1->Panels->Items[0]->Text="";

}

else

{

ServerSocket1->Active=true;

ckListen->Checked=true;

ClientSocket1->Active=false;

StatusBar1->Panels->Items[0]->Text="监听..." ;

}

ckConnect->Enabled=!(ckListen->Checked);

当有客户加入时,向所有的客户发出通知:并在自已的mmTalk加入此消息:所以在ServerSocket1的OnAccept事件中加入如下代码:

int i;

AnsiString str1="服务器消息:"+Socket->RemoteHost+"加入";

for(i=0;iSocket->ActiveConnections;i++)

ServerSocket1->Socket->Connections[i]->SendText("服务器消息:"+Socket->RemoteHost+"加入");

StatusBar1->Panels->Items[0]->Text=str1;

mmTalk->Lines->Add(str1);

当客户机通知服务器读信息时,首先读出字符串,然后把读到的字符串发送到每一台连接的客户,并在自已的mmTalk中加入客户发送来的字符串。所以,在TServerSocket的OnClientRead事件中加入以下代码:

AnsiString str1=Socket->ReceiveText();

mmTalk->Lines->Add(str1);

int i;

for(i=0;iSocket->ActiveConnections;i++)

ServerSocket1->Socket->Connections[i]->SendText(str1);

程序作为客户机的设置:

当单击"连接"时,如果还未连接,则询问要连接的主机,然后连接之,屏蔽"监听";如果已经连接,则断开连接。"监听"使能。所以,在ckConnect的OnClick事件中加入以下代码:

if(ClientSocket1->Active)

{

ClientSocket1->Active=false;

ckConnect->Checked =false;

}

else

{

AnsiString Server="localhost";

if(InputQuery("连接","请输入要连接的主机地址:",Server))

{

ClientSocket1->Host=Server;

ClientSocket1->Active=true;

ckConnect->Checked =true;

}

}

ckListen->Enabled= !(ckConnect->Checked);

当连接服务器成功时,在状态栏中显示此信息,所以,在ClientSocket1的

ClientSocket1Connect中加入:

StatusBar1->Panels->Items[0]->Text ="连接到主机:"+Socket->RemoteHost;

当服务器发送字符串来时,把它加入mmTalk中,但如果本字符串就是自已发送的(因为服务器会把收到的消息发给每一客户),为条信息就是重复的,所以,要比较mmTalk中最后两条信息是否相同,如果相同,则删除重复信息。代码如下:

mmTalk->Lines->Add(Socket->ReceiveText());

int i=mmTalk->Lines->Count-1;

if(mmTalk->Lines->Strings[i]==mmTalk->Lines->Strings[i-1])

mmTalk->Lines->Delete(i);

公用部分

当在edTalk输入交谈内容,按回车键表示输入完成,此时把交谈内容发送出去并清除edTalk 的内容。在发送信息时,要看本程序是作为服务器还是客户机,如果是服务器则把信息发送到每一个客户;如果是作为客户则把信息发送到服务器。代码如下:

if(Key==13)

{

mmTalk->Lines->Add(edName->Text+":"+edTalk->Text);

if(ckListen->Enabled&&ckConnect->Enabled==false)

//"监听"有效,"连接"无效。表示是服务器

{

int i;

for(i=0;iSocket->ActiveConnections;i++)

ServerSocket1->Socket->Connections[i]->SendText(edName->Text+":"+edTalk->Text);

}

else

{

ClientSocket1->Socket->SendText(edName->Text+":"+edTalk->Text);

}

edTalk->Text="";

}

mmTalk的内容不可能永远增加,所以当它有100行时就清空它,在mmTalk的OnChange 事件中检查:

if(mmTalk->Lines->Count>=100)mmTalk->Lines->Clear();

当然你也可以双击mmTalk来清空它,在mmTalk的OnDblClick事件中加入:

mmTalk->Lines->Clear();

当你觉得谈话的内容很有意思,你可以单击bbtSave打开保存对话框设置保存特性,所以在bbtSave的onClick中加入代码:

if(sdTalk->Execute())

mmTalk->Lines->SaveToFile(sdTalk->FileName);

OK,我们的闲聊程序就完成了,在局域网中试试吧?如果你只有一台机器,客户程序在连接时服务器时输入localhost或你机器的名字就可以了。

熟悉了这两个组件我们就可以写如联众游戏一样的网络游戏了(至少理论上如此),我也正想写一个网上赌博程序去诈骗我的同事,千万不要告诉他们哦!:=)

ServerSocket和ClientSocket控件事件

2012-05-09 13:49 达内培训

本文继认识C++Builder中的WinSock控件及其相关类、TServerSocket和TClientSocket控件的属性后将向你展示ServerSocket和ClientSocket控件的事件,希望能对你有所帮助。

1.ServerSocket的事件

onclientconnect:客户与服务器连接且服务器接收申请后,产生此事件。onclientdisconnect:当和服务器连接的某一个客户机关闭连接后产生此事件。

onGetSocket:一个服务器可以接收多个客户Socket的连接申请。

onGetThread:当ClientType属性值设为StrThreadBlocking时,服务器会产生一个单独的线程来与客户的连接。

onAccept:服务器接收客户的连接申请后,产生此事件。

onClientRead:客户机发送数据到服务器时产生的事件。

2.ClentSocket事件

onConnect:当客户端与服务器端连接上后,产生此事件。

onConnecing:当客户端与服务器端进行连接操作时,产生此事件。

onDisconnect:当客户端关闭操作后产生此事件。

onError:在客户与服务器在建立和通信过程中,如果产生错误时,产生此事件。

onLookup:当客户在计算机网络中寻找服务器时,产生此事件。

onRead:数据到达时产生此事件。

完整的学习才能让你进步更快!

TServerSocket和TClientSocket控件

2012-05-09 13:49 达内

本文是用WinSock控件编写网络聊天器的第二部分知识内容,希望你能认真参悟。

以下为正文:

1.ServerSocket的控件属性

threadcachsize:创建服务器线程的最在数目。

port:确定服务器的监视端口。

service:客户通过此属性来识别服务器端口。

2.ClientSocket的控件属性

Socket:此属性参数是应用程序之间通信的端点。

Address:此属性参数为字符串类型,客户端确定服务器端的IP地址。

Host:服务器端的主机名称。

Post:服务器端的监视端口。

Servce:用来识别服务器端口。

Active:确定Socket是否可用(true表示可用)。

ClientType:指定客户机采用哪一种方式(异步/同步)来通信。

编写聊天程序

2012-05-09 13:40 达内

关注本站的朋友一定了解,本文是用WinSock控件编写网络聊天器的最后部分,希望本文能对你有帮助。另外达内的老师希望你能将它付出实践,那将让你收获更大!

打开C++Builder 5.0新建一个工程,新建一个Form1窗体,在Form1窗体中添加以下控件:

ClientSocket控件:

1个ServerSocket控件:

1 个Button控件:

4个Label控件:

2个Memo控件:

1个Edit控件:

2个TreeView控件:

1个StatusBar控件:

1个添加控件

各控件属设置如下:

Form1窗体:Caption="网络聊天器".

ServerSocket:

Name=ServerSocket1;port=10000;ServerType=stNonBlocking;ThreadCacheSize=10. ClientSocket: Name=ClientSocket1;port=10000;ClientType=stNonBlocking.

Mome:Name=Mome1;ScrollBars=ssVertical. TreeView:Name=TreeView1; Button:

第一个:Name=Btnlisten;Caption="监听";

第二个:Name=Btnconnect;Caption="连接";

第三个:Name=Btndisconnect;Caption="断开";

第一个:Name=BtnExit;Caption="退出"; Label:

第一个:Name=Label1;Caption="发送";

第二个: Name=Label2;Caption="在线客户". Edit:

第一个:Name=Edit1;

第二个: Name=Edit2; StatusBar:Name=StatusBar1;

设置好以上属性值,就可以进行代码的编写了,源程序代码如下:

//-------------------------- //"Unit1.h"的源程序//-------------------

#ifndef Unit1H

#define Unit1H

//--------------------------------------------------------------------

#include

#include

#include

#include

#include

#include

#include

#include

#include

//---------------------------------------------------------------------

class TForm1 : public TForm

{

__published: // IDE-managed Components

TClientSocket *ClientSocket1;

TServerSocket *ServerSocket1;

TMemo *Memo1;

TStatusBar *StatusBar1;

TEdit *Edit1;

TLabel *Label1;

TTreeView *TreeView1;

TLabel *Label2;

TEdit *Edit2;

TButton *Btnlisten;

TButton *Btnconnect;

TButton *Btndisconnect;

TButton *BtnExit;

void __fastcall FormCreate(TObject *Sender);

void __fastcall ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket);

void __fastcall ServerSocket1Accept(TObject *Sender, TCustomWinSocket *Socket);

void __fastcall ServerSocket1ClientDisconnect(TObject *Sender, TCustomWinSocket *Socket);

void __fastcall ClientSocket1Disconnect(TObject *Sender, TCustomWinSocket *Socket);

void __fastcall ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent,

int &ErrorCode);

void __fastcall ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket);

void __fastcall ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket);

void __fastcall Edit1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift);

void __fastcall ClientSocket1Lookup(TObject *Sender, TCustomWinSocket *Socket);

void __fastcall TreeView1Change(TObject *Sender, TTreeNode *Node); void __fastcall BtnlistenClick(TObject *Sender);

void __fastcall BtnconnectClick(TObject *Sender);

void __fastcall BtndisconnectClick(TObject *Sender);

void __fastcall BtnExitClick(TObject *Sender);

private:

bool IsServer;

String Server;

// User declarations

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//-------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//-------------------------------------------------------------------------

#endif //"Unit1.cpp"源程序//----------------------------------------------- #include

#include

#pragma hdrstop #include "Unit1.h"

//--------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//--------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

IsServer=false;

Server="";

}

//--------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)

{

Btndisconnect->Enabled=false;

} //------------------------------------------------------------------------

//当用户提出连接请求后,客户端会触发OnCreate事件

void __fastcall TForm1::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket)

{

StatusBar1->SimpleText="连接到:"+Server;

TreeView1->Items->Add(TreeView1->Selected ,Server);

Memo1->Lines->Clear();

//定义mouse的类型

Form1->Cursor=crDefault ;

Edit1->Cursor=crDefault;

Memo1->Cursor=crDefault;

//产生一个新的监听}

//-------------------------------------------------------------------------

//在服务器接受了客户的请求后会触发OnAccept事件

void __fastcall TForm1::ServerSocket1Accept(TObject *Sender, TCustomWinSocket *Socket)

{ Memo1->Lines->Clear();

IsServer=true;

StatusBar1->SimpleText="连接到:"+Socket->LocalHost;

TreeView1->Items->Add(TreeView1->Selected ,Socket->LocalHost);

}

//-------------------------------------------------------------------------

//断开后继续监听

void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender, TCustomWinSocket *Socket)

{

StatusBar1->SimpleText="正在监听...";

}

//-------------------------------------------------------------------------

//客户端关闭连接后产生的事件

void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender, TCustomWinSocket *Socket)

{

Btnlisten->Enabled=true;

Btnconnect->Enabled=true;

Btndisconnect->Enabled=false;

StatusBar1->SimpleText="";

}

//-------------------------------------------------------------------------

// 通信过程中产生错误时产生的事件

void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) {

ShowMessage("错误!!! 无法连接到服务器");

ErrorCode=0;

Btnlisten->Enabled=true;

Btnconnect->Enabled=true;

Btndisconnect->Enabled=false;

StatusBar1->SimpleText="";

//定义mouse的类型

Form1->Cursor=crDefault ;

Edit1->Cursor=crDefault;

Memo1->Cursor=crDefault;

Form1->Caption ="网络聊天器";

}

//-------------------------------------------------------------------------

//客户端接收数据

void __fastcall TForm1::ClientSocket1Read(TObject *Sender,

TCustomWinSocket *Socket)

{

Memo1->Lines->Add(Socket->ReceiveText());

}

//---------------------------------------------------------------------------

//服务器端接收数据

void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,

TCustomWinSocket *Socket)

{

Memo1->Lines->Add(Socket->ReceiveText());

}

//-------------------------------------------------------------------------

//在建立连接后,双方就可以在Edit1中输入谈话内容开始进

//行交谈了,按下Enter键后,将所在行的文本发送出去

void __fastcall TForm1::Edit1KeyDown(TObject *Sender, WORD &Key,

TShiftState Shift)

{

AnsiString Data;

if(Key==VK_RETURN)

{if (Edit2->Text!="") //在没有选择发送的主机名时不能进行发送操作

{if(IsServer) //服务器端发出的数据

{Data= "["+TimeToStr(Now())+"]:("+ServerSocket1->Socket->LocalHost+")对

"+"("+Edit2->Text+")"+"说:"+Edit1->Text;

ServerSocket1->Socket->Connections[TreeView1->Selected->Index]->SendText(Data); Memo1->Lines->Add(Data);

Edit1->Text="";}

else //客户端发出的数据

{ Data="["+TimeToStr(Now())+"]:("+ClientSocket1->Socket->LocalHost+")对"+"("+Edit2->Text +")"+"说:"+Edit1->Text;

ClientSocket1->Socket->SendText(Data);

Memo1->Lines->Add(Data);

Edit1->Text="";}

}

else

ShowMessage("错误!!! 没有选择发送的主机名");

}

}

//---------------------------------------------------------------------------

//在网络中搜索服务器端时产生的事件

void __fastcall TForm1::ClientSocket1Lookup(TObject *Sender,

TCustomWinSocket *Socket)

{ //定义mouse的类型

Form1->Cursor=crHourGlass ;

Edit1->Cursor=crHourGlass;

Memo1->Cursor=crHourGlass;

}

//选择发向数据的主机名

void __fastcall TForm1::TreeView1Change(TObject *Sender, TTreeNode *Node)

{

Edit2->Text=TreeView1->Selected->TreeView->Selected->Text;

StatusBar1->SimpleText="连接到:"+TreeView1->Selected->TreeView->Selected->Text; } //监听

void __fastcall TForm1::BtnlistenClick(TObject *Sender)

{

ClientSocket1->Active=false;

ServerSocket1->Active=true;

StatusBar1->SimpleText="正在监听...";

Form1->Caption =Form1->Caption+"--服务器端";

Btnlisten->Enabled=false;

Btnconnect->Enabled=false;

}

//连接

void __fastcall TForm1::BtnconnectClick(TObject *Sender)

{

if(InputQuery("连接到服务器","输入服务器地址:",Server))

{

if(Server.Length() >0){

ClientSocket1->Host=Server; //确定服务器的主机名

ClientSocket1->Active=true;

Btnlisten->Enabled=false;

Btnconnect->Enabled=false;

Btndisconnect->Enabled=true;

Form1->Caption =Form1->Caption+"--客户端";}

}

}

//断开

void __fastcall TForm1::BtndisconnectClick(TObject *Sender) {

//按下断开

ClientSocket1->Close();

}

//---------------------------------------------------------------------------

//退出

void __fastcall TForm1::BtnExitClick(TObject *Sender)

{

ClientSocket1->Close();

ServerSocket1->Close();

Form1->Close();

}

相关文档
相关文档 最新文档