赛迪网 > IT技术 C/C++ > 文章
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

C++Builder创建基于Internet点对点Chat

发布时间:2006.04.07 01:26     来源:赛迪网社区    作者:周新栋

创建基于Internet的应用程序,你也许会想到复杂的WinSock编程。不过,C++ Builder3提供了新的WebBroker的Internet套件,其中的TClientSocket和TServerSocket组件封装了Windows的有关API,大大简化了WinSock编程。要通过Internet传输数据,至少需要一对Socket,一个Socket在客户端,另一个Socket在服务器端。其实TClientSocket、TServerSocket组件并不是Socket对象,其属性Socket将返回各自的Socket对象。TClientSocket用来处理客户端到服务器端之间的socket连接,TServerSocket用来处理由客户端发来的socket连接,一旦客户端和服务器端都接通了socket,客户端和服务器端就可以相互通信了。

建立一新项目,创建应用程序的用户界面:

1.将组件页切换到Internet页,放一个TServerSocket组件和一个TClientSocket组件到窗体上,这样应用程序既可以是TCP/IP服务器,也可以是TCP/IP客户。将Port属性都设为同一个值(如1000),确定Socket之间的连接类型为NonBlocking(非阻塞方式)。

2.放两个TMemo组件到窗体上,用来分别显示双方的谈话内容,将Memo2的ReadOnly属性设为True。

3.在窗体的顶部放上一个Panel组件,在其上放三个按钮:监听(btnlisten)、连接(btnconnect)、断开(btndisconnect),用来启动相应的操作。

4.在窗体底部放一个StatusBar组件,将其SimplePanel属性设为True,在相应的事件处理程序中改变状态条信息,让用户随时了解连接状态。

打开头文件,在窗体类的Private段添加两个私有成员: bool IsServer;String Server。双方通信时需同时运行Chat程序,IsServer用来确定哪个Chat程序处于服务器端,Server用来存放服务器的主机名。建立窗体类的构造器如下:

fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    IsServer=false;
    Server="localhost";
}

这里Server被缺省设为localhost,这样程序可以在没有连入Internet的单机上进行调试。在Windows子目录下你可以找到hosts.sam文件中,在该文件中已经将本机IP地址127.0.0.1定义了主机名:

localhost。

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    btndisconnect- >Enabled=false;
}

程序运行后,如果用户按下"监听"钮,则将该程序设为服务器端,这时应将TServerSocket的Active属性设为True,使服务器自动进入监听状态。

void __fastcall TForm1::btnlistenClick(TObject *Sender)
{
    ClientSocket1- >Active=false;
    ServerSocket1- >Active=true;
    StatusBar1- >SimpleText="正在监听...";
    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;
        }
    }
}

当用户提出连接请求后,客户端会触发OnCreate事件,程序先在状态条中显示连接信息,然后将显示对方谈话内容的Memo2清空,准备开始交谈。

void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
      TCustomWinSocket *Socket)
{
    StatusBar1- >SimpleText="连接到:"+Server;
    Memo2- >Lines- >Clear();
}

在服务器接受了客户的请求后会触发OnAccept事件,在这个事件处理程序中将标志服务器端的变量IsServer设为True,并准备开始交谈。

void __fastcall TForm1::ServerSocket1Accept(
TObject *Sender,
      TCustomWinSocket *Socket)
{
    Memo2- >Lines- >Clear();
    IsServer=true;
    StatusBar1- >SimpleText="连接到:"
+Socket- >RemoteAddress;
}

在建立连接后,双方就可以在Memo1中输入谈话内容开始进行交谈了,按下Enter键后,将所在行的文本发送出去。服务器端的Socket的Connections属性返回一个数组,该数组由服务器当前活动的连接组成。

void __fastcall TForm1::Memo1KeyDown(
TObject *Sender, WORD &Key,
      TShiftState Shift)
{
    if(Key==VK_RETURN){
        if(IsServer)
            ServerSocket1- >Socket- >Connections[0]- >SendText(
Memo1- >Lines- >Strings[Memo1- >Lines- >Count-1]);
        else
            ClientSocket1- >Socket- >SendText(
Memo1- >Lines- >Strings[Memo1- >Lines- >Count-1]);
    }
}

在本例中我们采用非阻塞传输方式,当其中的一方进行写操作时,另一方会触发OnRead事件(客户端)或OnClientRead事件(服务器端),这两个事件的处理程序只是将接收到的内容添加到Memo2的后面。

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

如果在用户建立连接后单击"断开"钮,将断开客户端与服务器的连接,服务器端将触发OnClientDisconnect事件,而客户端则会触发OnDisconnect事件,这时服务器端应回到监听状态,等待用户的连接;而客户端将返回到连接前的状态,等待用户再次建立连接,如果有不止一个服务器的话,可以选择连接到其他的服务器上。

void __fastcall TForm1::btndisconnectClick(
TObject *Sender)
{
    ClientSocket1- >Close();
}
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::ClientSocke
t1Error(TObject *Sender,
      TCustomWinSocket *Socket, 
TErrorEvent ErrorEvent, int &ErrorCode)
{
StatusBar1- >SimpleText="无法连接到:
"+Socket- >RemoteHost;
    ErrorCode=0;
}

以上代码在C++ Builder3 C/S版中编译、运行通过。

(T113)


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· 用C++ Builder为计算机增加启动日志 (04-06) · C++Builder在WIN2000环境下编制Service (04-06)
· 技巧应用篇—C++在网页设计中的应用 (04-05) · C++ Builder用ActiveX显示Flash动画 (04-05)
· 应用实例:VC++实现广告窗口自动关闭 (03-13) · VC++中的Progress控件如何使用 (02-21)
· Internet防火墙基础技术综述 (02-20) · 在C++程序中导出Word文档的方法 (02-17)
· C++中控制Windows关机的实用技巧 (02-17) · C++中控制Windows关机的实用技巧 (02-15)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
[政务][电信][金融][农业][制造业][中小企业]
[CIO][ERP][协同][IT管理][中间件][电子商务]
[政策][地方][专家][评估][辞典][博客][社区]
· 专题:一路畅通构想曲——让出行不再遭遇堵车
· CIO工作亲历:企业ERP选型不能忽视"选人关"
· 综述:信息化建设给中国监狱带来的各种变化
· 金融业风险管理和法规遵从有五点需考虑的因素
· 保险业CIO关注:该如何建立统一高效的CRM体系
· 调查显示:多数CIO对IT规划仍存在困惑和误解
  博客·论坛 ·曾剑秋·项立刚·Java学习·网管