• 注册
  • 关于作者
    企业认证:趣记站长
    关注 6 粉丝 4 喜欢 9 内容 992
    江西省·南昌市
    聊天 送礼
    • 查看作者
    • 用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的描述 发给客户端,一旦客户端确认了此描述,连接就建立了。在本文中的聊天程序用的就是监听连接,

      使用C++Builder在WIN2000环境下编制Service
      用C++ Builder实现VFP数据库开发,用BCB开发有身份认证功能的Email程序,BCB动态生成30个按钮对象,BCB不让应用程序显示在任务栏上的方法,利用C++Builder自定义Windows窗体“系统菜单”,用程序实现文件的关联,数字小键盘指法练习,用C++ Builder开发多层数据库应用程序,在C++ Builder6上使用Boost正则表达式库,C++Builder使用经验谈,用C++ Builder对图像进行特殊效果处理,CBuilder中帮助文件的连接及显示讨论,BCB客户端tuxedo开发实例,在BCB下使用GExperts的Debug功能,BCB编写DLL终极手册,在拷贝、删除文件时显示飞行的文件夹动画,用BCB实现超星格式转换为BMP格式,在C++Builder中使用Compress Html Help,在bcb里实现像Winamp那样具有吸附效果的磁性窗口,利用BCB巧建WEB浏览器
      C++ Builder

      即服务器设置连接个数后进行监听,客户端进行对服务器端的连接,这样就可以进行相互通信了。

      二.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();

      }

      //编写完程序代码后,就要对源程序进行编译了,编译方法如下:

      1.在菜单 project \ options 下,选择Packages 页,去掉Build with runtime packages 项的勾, 然后选择Linker 页,去掉 Use dynamic RTL 的勾,然后按“确定”按钮。

      2.在菜单 project \ options 下,选择 Compiler 页,按下 Release 按钮,然后按“确定”按钮。

      3.在菜单 Run \ Run (或F9) 进行编译就行。 用这种方法编译的可执行文件容量比较小, 而且可以在没有安装C++的系统中运行。在运行时 可单机也可多机操作,但必须要有一个主机打开程序的“监听”,其它客户机进行连接就行了。 快快来下载,编写自己的聊天程序吧!

      用游戏操纵杆摸拟鼠标
      用C++ Builder实现VFP数据库开发,用BCB开发有身份认证功能的Email程序,BCB动态生成30个按钮对象,BCB不让应用程序显示在任务栏上的方法,利用C++Builder自定义Windows窗体“系统菜单”,用程序实现文件的关联,数字小键盘指法练习,用C++ Builder开发多层数据库应用程序,在C++ Builder6上使用Boost正则表达式库,C++Builder使用经验谈,用C++ Builder对图像进行特殊效果处理,CBuilder中帮助文件的连接及显示讨论,BCB客户端tuxedo开发实例,在BCB下使用GExperts的Debug功能,BCB编写DLL终极手册,在拷贝、删除文件时显示飞行的文件夹动画,用BCB实现超星格式转换为BMP格式,在C++Builder中使用Compress Html Help,在bcb里实现像Winamp那样具有吸附效果的磁性窗口,利用BCB巧建WEB浏览器
      C++ Builder

    • 0
    • 0
    • 0
    • 60
    • 单栏布局 侧栏位置: