认识C++Builder中的WinSock控件及其相关类

 
一,认识C++Builder中的WinSock控件及其相关类
  WinSock是一组用C语言写的API,用于通过Internet进行数据传输。通过WinSock编程可以获得更大的灵活性。编写WinSock应用程序本来是很麻烦的,不过,在C++   Builder   5.0中,您并不需要直接与WinSock中的API打交道,因为C++   Builder   5.0新增加了TClientSocket控件和TserverSocket控件,这两个控件封装了Windows的有关API,使得对WinSock的访问大大简化。用Socket   建立的连接是建立在TCP/IP协议基础上的,同时也支持其它相关的协议,如XNS、DECnet以及   IPX/SPX等。Socket的连接必须要建立有一个服务器端(Server)和一个客户端(Client)。在C++   Builder   5.0中分别用TClientSocket控件和TServerSocket控件来操纵客户端Socket与服务器端Socket的   连接和通信。这两个控件用于管理服务器和客户的连接,它们本身并不是Socket对象,操纵   Socket对象的是TCustomWinSocket及其派生类,如TClientWinSocket、TserverWinSocket   .   TServerClientWinSocket等。

  Socket之间的连接可以分为三种类型:客户端连接、监听连接以及   服务器端连接,所谓客户端连接,是指由客户端的Socket提出连接请求,要连接的目标是服务   器端的Socket。为此,客户端的Socket必须首先描述它要连接的服务器端Socket(主要是指服务器   端Socket的地址和端口号),然后再定位所要连接的服务器端Socket,找到以后,就向服务器端   Socket请求连接。当然,服务器端的Socket此时未必正好处于准备好状态,不过,服务器端的   Socket会自动维护客户请求连接的队列,然后在它认为合适的时候向客户端Socket发出“允许连接”   (Accept)的信号,这时客户端Socket与服务器端Socket的连接就建立了。所谓监听连接,服务器端   Socket并不定位具体的客户端Socket,而是处于等待连接的状态。当服务器端Socket监听到或者说   接收到客户端Socket的连接请求,它就响应客户端Socket的请求建立一个新的Socket句柄并与客户   端连接,而服务器端Socket继续处于监听状态,还可以接收其它客户端Socket的连接请求。所谓服   务器端连接,是指当服务器端Socket接收到客户端Socket的连接请求后,就把服务器端Socket的描述   发给客户端,一旦客户端确认了此描述,连接就建立了。在本文中的聊天程序用的就是监听连接,   即服务器设置连接个数后进行监听,客户端进行对服务器端的连接,这样就可以进行相互通信了。  

二.TServerSocket和TClientSocket控件的属性

1.ServerSocket的控件属性  

threadcachsize:创建服务器线程的最在数目。  
port:确定服务器的监视端口。  
service:客户通过此属性来识别服务器端口。  

2.ClientSocket的控件属性  

Socket:此属性参数是应用程序之间通信的端点。  
Address:此属性参数为字符串类型,客户端确定服务器端的IP地址。  
Host:服务器端的主机名称。  
Post:服务器端的监视端口。  
Servce:用来识别服务器端口。  
Active:确定Socket是否可用(true表示可用)。  
ClientType:指定客户机采用哪一种方式(异步/同步)来通信。
 
三.ServerSocket和ClientSocket控件的事件

1.ServerSocket的事件  
onclientconnect:客户与服务器连接且服务器接收申请后,产生此事件。  
onclientdisconnect:当和服务器连接的某一个客户机关闭连接后产生此事件。  
onGetSocket:一个服务器可以接收多个客户Socket的连接申请。  
onGetThread:当ClientType属性值设为StrThreadBlocking时,服务器会产生一个单独的线程来与客户的连接。  
onAccept:服务器接收客户的连接申请后,产生此事件。  
onClientRead:客户机发送数据到服务器时产生的事件。

2.ClentSocket事件  
onConnect:当客户端与服务器端连接上后,产生此事件。  
onConnecing:当客户端与服务器端进行连接操作时,产生此事件。  
onDisconnect:当客户端关闭操作后产生此事件。  
onError:在客户与服务器在建立和通信过程中,如果产生错误时,产生此事件。  
onLookup:当客户在计算机网络中寻找服务器时,产生此事件。  
onRead:数据到达时产生此事件。
 
 
四.ServerSocket和ClientSocket的方法

1.Open方法  
  此方法适用于ServerSocket和CilentSocket进行建立连接,原型如下:   void-Fastcall   open(void);  

2.Close方法
  此方法适用于ServerSocket和CilentSocket进行关闭连接,原型如下:   void-Fastcall   close(void);  

五.编写聊天程序

  打开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   <Classes.hpp>
#include   <Controls.hpp>
#include   <StdCtrls.hpp>
#include   <Forms.hpp>
#include   <ScktComp.hpp>
#include   <ExtCtrls.hpp>
#include   <ComCtrls.hpp>
#include   <Menus.hpp>
#include   <ToolWin.hpp>
//---------------------------------------------------------------------
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   <vcl.h>
#include   <stdio.h>
#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();
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值