-
c语言入门之用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();
}
//编写完程序代码后,就要对源程序进行编译了,编译方法如下:
1.在菜单 project \ options 下,选择Packages 页,去掉Build with runtime packages 项的勾, 然后选择Linker 页,去掉 Use dynamic RTL 的勾,然后按“确定”按钮。
2.在菜单 project \ options 下,选择 Compiler 页,按下 Release 按钮,然后按“确定”按钮。
3.在菜单 Run \ Run (或F9) 进行编译就行。 用这种方法编译的可执行文件容量比较小, 而且可以在没有安装C++的系统中运行。在运行时 可单机也可多机操作,但必须要有一个主机打开程序的“监听”,其它客户机进行连接就行了。 快快来下载,编写自己的聊天程序吧!
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();
}
//编写完程序代码后,就要对源程序进行编译了,编译方法如下:
1.在菜单 project \ options 下,选择Packages 页,去掉Build with runtime packages 项的勾, 然后选择Linker 页,去掉 Use dynamic RTL 的勾,然后按“确定”按钮。
2.在菜单 project \ options 下,选择 Compiler 页,按下 Release 按钮,然后按“确定”按钮。
3.在菜单 Run \ Run (或F9) 进行编译就行。 用这种方法编译的可执行文件容量比较小, 而且可以在没有安装C++的系统中运行。在运行时 可单机也可多机操作,但必须要有一个主机打开程序的“监听”,其它客户机进行连接就行了。 快快来下载,编写自己的聊天程序吧!
最新更新
Objective-C语法之代码块(block)的使用
VB.NET eBook
Add-in and Automation Development In VB.NET 2003 (F
Add-in and Automation Development In VB.NET 2003 (8
Add-in and Automation Development in VB.NET 2003 (6
Add-in and Automation Development In VB.NET 2003 (5
AddIn Automation Development In VB.NET 2003 (4)
AddIn And Automation Development In VB.NET 2003 (2)
Addin and Automation Development In VB.NET 2003 (3)
AddIn And Automation Development In VB.NET 2003 (1)
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
武装你的WEBAPI-OData入门
武装你的WEBAPI-OData便捷查询
武装你的WEBAPI-OData分页查询
武装你的WEBAPI-OData资源更新Delta
5. 武装你的WEBAPI-OData使用Endpoint 05-09
武装你的WEBAPI-OData之API版本管理
武装你的WEBAPI-OData常见问题
武装你的WEBAPI-OData聚合查询
OData WebAPI实践-OData与EDM
OData WebAPI实践-Non-EDM模式