全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1440
推到 Plurk!
推到 Facebook!

用WinSock控制項編寫網路聊天器

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-05-30 00:46:27 IP:61.64.xxx.xxx 未訂閱
用WinSock控制項編寫網路聊天器 http://www.yesky.com/20001218/146504.shtml b>一.認識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 $#@60;Classes.hpp$#@62; #include $#@60;Controls.hpp$#@62; #include $#@60;StdCtrls.hpp$#@62; #include $#@60;Forms.hpp$#@62; #include $#@60;ScktComp.hpp$#@62; #include $#@60;ExtCtrls.hpp$#@62; #include $#@60;ComCtrls.hpp$#@62; #include $#@60;Menus.hpp$#@62; #include $#@60;ToolWin.hpp$#@62; //--------------------------------------------------------------------- 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 $#@60;vcl.h$#@62; #include $#@60;stdio.h$#@62; #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-$#@62;Enabled=false; } //--------------------------------------------------------------------------- //當用戶提出連接請求後,用戶端會觸發OnCreate事件 void __fastcall TForm1::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket) { StatusBar1-$#@62;SimpleText="連接到:" Server; TreeView1-$#@62;Items-$#@62;Add(TreeView1-$#@62;Selected ,Server); Memo1-$#@62;Lines-$#@62;Clear(); //定義mouse的類型 Form1-$#@62;Cursor=crDefault ; Edit1-$#@62;Cursor=crDefault; Memo1-$#@62;Cursor=crDefault; //產生一個新的監聽 } //--------------------------------------------------------------------------- //在伺服器接受了客戶的請求後會觸發OnAccept事件 void __fastcall TForm1::ServerSocket1Accept(TObject *Sender, TCustomWinSocket *Socket) { Memo1-$#@62;Lines-$#@62;Clear(); IsServer=true; StatusBar1-$#@62;SimpleText="連接到:" Socket-$#@62;LocalHost; TreeView1-$#@62;Items-$#@62;Add(TreeView1-$#@62;Selected ,Socket-$#@62;LocalHost); } //--------------------------------------------------------------------------- //斷開後繼續監聽 void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender, TCustomWinSocket *Socket) { StatusBar1-$#@62;SimpleText="正在監聽..."; } //--------------------------------------------------------------------------- //用戶端關閉連接後產生的事件 void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender, TCustomWinSocket *Socket) { Btnlisten-$#@62;Enabled=true; Btnconnect-$#@62;Enabled=true; Btndisconnect-$#@62;Enabled=false; StatusBar1-$#@62;SimpleText=""; } //--------------------------------------------------------------------------- // 通信過程中產生錯誤時產生的事件 void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) { ShowMessage("錯誤!!! 無法連接到伺服器"); ErrorCode=0; Btnlisten-$#@62;Enabled=true; Btnconnect-$#@62;Enabled=true; Btndisconnect-$#@62;Enabled=false; StatusBar1-$#@62;SimpleText=""; //定義mouse的類型 Form1-$#@62;Cursor=crDefault ; Edit1-$#@62;Cursor=crDefault; Memo1-$#@62;Cursor=crDefault; Form1-$#@62;Caption ="網路聊天器"; } //--------------------------------------------------------------------------- //用戶端接收資料 void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket) { Memo1-$#@62;Lines-$#@62;Add(Socket-$#@62;ReceiveText()); } //--------------------------------------------------------------------------- //伺服器端接收資料 void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket) { Memo1-$#@62;Lines-$#@62;Add(Socket-$#@62;ReceiveText()); } //--------------------------------------------------------------------------- //在建立連接後,雙方就可以在Edit1中輸入談話內容開始進 //行交談了,按下Enter鍵後,將所在行的文本發送出去 void __fastcall TForm1::Edit1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { AnsiString Data; if(Key==VK_RETURN) {if (Edit2-$#@62;Text!="") //在沒有選擇發送的主機名時不能進行發送操作 {if(IsServer) //伺服器端發出的資料 {Data= "[" TimeToStr(Now()) "]:(" ServerSocket1-$#@62;Socket-$#@62;LocalHost ")對" "(" Edit2-$#@62;Text ")" "說:" Edit1-$#@62;Text; ServerSocket1-$#@62;Socket-$#@62;Connections[TreeView1-$#@62;Selected-$#@62;Index]-$#@62;SendText(Data); Memo1-$#@62;Lines-$#@62;Add(Data); Edit1-$#@62;Text="";} else //用戶端發出的資料 { Data="[" TimeToStr(Now()) "]:(" ClientSocket1-$#@62;Socket-$#@62;LocalHost ")對" "(" Edit2-$#@62;Text ")" "說:" Edit1-$#@62;Text; ClientSocket1-$#@62;Socket-$#@62;SendText(Data); Memo1-$#@62;Lines-$#@62;Add(Data); Edit1-$#@62;Text="";} } else ShowMessage("錯誤!!! 沒有選擇發送的主機名"); } } //--------------------------------------------------------------------------- //在網路中搜索伺服器端時產生的事件 void __fastcall TForm1::ClientSocket1Lookup(TObject *Sender, TCustomWinSocket *Socket) { //定義mouse的類型 Form1-$#@62;Cursor=crHourGlass ; Edit1-$#@62;Cursor=crHourGlass; Memo1-$#@62;Cursor=crHourGlass; } //選擇發向資料的主機名 void __fastcall TForm1::TreeView1Change(TObject *Sender, TTreeNode *Node) { Edit2-$#@62;Text=TreeView1-$#@62;Selected-$#@62;TreeView-$#@62;Selected-$#@62;Text; StatusBar1-$#@62;SimpleText="連接到:" TreeView1-$#@62;Selected-$#@62;TreeView-$#@62;Selected-$#@62;Text; } //監聽 void __fastcall TForm1::BtnlistenClick(TObject *Sender) { ClientSocket1-$#@62;Active=false; ServerSocket1-$#@62;Active=true; StatusBar1-$#@62;SimpleText="正在監聽..."; Form1-$#@62;Caption =Form1-$#@62;Caption "--伺服器端"; Btnlisten-$#@62;Enabled=false; Btnconnect-$#@62;Enabled=false; } //連接 void __fastcall TForm1::BtnconnectClick(TObject *Sender) { if(InputQuery("連接到伺服器","輸入伺服器位址:",Server)) { if(Server.Length() $#@62;0){ ClientSocket1-$#@62;Host=Server; //確定伺服器的主機名 ClientSocket1-$#@62;Active=true; Btnlisten-$#@62;Enabled=false; Btnconnect-$#@62;Enabled=false; Btndisconnect-$#@62;Enabled=true; Form1-$#@62;Caption =Form1-$#@62;Caption "--用戶端";} } } //斷開 void __fastcall TForm1::BtndisconnectClick(TObject *Sender) { //按下斷開 ClientSocket1-$#@62;Close(); } //--------------------------------------------------------------------------- //退出 void __fastcall TForm1::BtnExitClick(TObject *Sender) { ClientSocket1-$#@62;Close(); ServerSocket1-$#@62;Close(); Form1-$#@62;Close(); } //編寫完程式碼後,就要對根源程式進行編譯了,編譯方法如下: 1.在功能表 project \ options 下,選擇Packages 頁,去掉Build with runtime packages 項的勾, 然後選擇Linker 頁,去掉 Use dynamic RTL 的勾,然後按“確定”按鈕。 2.在功能表 project \ options 下,選擇 Compiler 頁,按下 Release 按鈕,然後按“確定”按鈕。 3.在功能表 Run \ Run (或F9) 進行編譯就行。 用這種方法編譯的可執行檔容量比較小, 而且可以在沒有安裝C 的系統中運行。在運行時 可單機也可多機操作,但必須要有一個主機打開程式的“監聽”,其他客戶機進行連接就行了。 快快來下載,編寫自己的聊天程式吧
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-06-01 08:40:24 IP:211.21.xxx.xxx 未訂閱
修正一下亂碼     
用WinSock控制項編寫網路聊天器
http://www.yesky.com/20001218/146504.shtml
b>一.認識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 
#include 
#include 
#include <Forms.hpp>
#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();
}
//編寫完程式碼後,就要對根源程式進行編譯了,編譯方法如下:     1.在功能表 project \ options 下,選擇Packages 頁,去掉Build with runtime packages 項的勾, 然後選擇Linker 頁,去掉 Use dynamic RTL 的勾,然後按“確定”按鈕。 
2.在功能表 project \ options 下,選擇 Compiler 頁,按下 Release 按鈕,然後按“確定”按鈕。 
3.在功能表 Run \ Run (或F9) 進行編譯就行。 用這種方法編譯的可執行檔容量比較小, 而且可以在沒有安裝C  的系統中運行。在運行時 可單機也可多機操作,但必須要有一個主機打開程式的“監聽”,其他客戶機進行連接就行了。 快快來下載,編寫自己的聊天程式吧     
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-06-01 08:46:07 IP:211.21.xxx.xxx 未訂閱
引言: 用WinSock控制項編寫網路聊天器 http://www.yesky.com/20001218/146504.shtml b>一.認識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 $#@60;Classes.hpp$#@62; #include $#@60;Controls.hpp$#@62; #include $#@60;StdCtrls.hpp$#@62; #include $#@60;Forms.hpp$#@62; #include $#@60;ScktComp.hpp$#@62; #include $#@60;ExtCtrls.hpp$#@62; #include $#@60;ComCtrls.hpp$#@62; #include $#@60;Menus.hpp$#@62; #include $#@60;ToolWin.hpp$#@62; //--------------------------------------------------------------------- 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 $#@60;vcl.h$#@62; #include $#@60;stdio.h$#@62; #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-$#@62;Enabled=false; } //--------------------------------------------------------------------------- //當用戶提出連接請求後,用戶端會觸發OnCreate事件 void __fastcall TForm1::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket) { StatusBar1-$#@62;SimpleText="連接到:" Server; TreeView1-$#@62;Items-$#@62;Add(TreeView1-$#@62;Selected ,Server); Memo1-$#@62;Lines-$#@62;Clear(); //定義mouse的類型 Form1-$#@62;Cursor=crDefault ; Edit1-$#@62;Cursor=crDefault; Memo1-$#@62;Cursor=crDefault; //產生一個新的監聽 } //--------------------------------------------------------------------------- //在伺服器接受了客戶的請求後會觸發OnAccept事件 void __fastcall TForm1::ServerSocket1Accept(TObject *Sender, TCustomWinSocket *Socket) { Memo1-$#@62;Lines-$#@62;Clear(); IsServer=true; StatusBar1-$#@62;SimpleText="連接到:" Socket-$#@62;LocalHost; TreeView1-$#@62;Items-$#@62;Add(TreeView1-$#@62;Selected ,Socket-$#@62;LocalHost); } //--------------------------------------------------------------------------- //斷開後繼續監聽 void __fastcall TForm1::ServerSocket1ClientDisconnect(TObject *Sender, TCustomWinSocket *Socket) { StatusBar1-$#@62;SimpleText="正在監聽..."; } //--------------------------------------------------------------------------- //用戶端關閉連接後產生的事件 void __fastcall TForm1::ClientSocket1Disconnect(TObject *Sender, TCustomWinSocket *Socket) { Btnlisten-$#@62;Enabled=true; Btnconnect-$#@62;Enabled=true; Btndisconnect-$#@62;Enabled=false; StatusBar1-$#@62;SimpleText=""; } //--------------------------------------------------------------------------- // 通信過程中產生錯誤時產生的事件 void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) { ShowMessage("錯誤!!! 無法連接到伺服器"); ErrorCode=0; Btnlisten-$#@62;Enabled=true; Btnconnect-$#@62;Enabled=true; Btndisconnect-$#@62;Enabled=false; StatusBar1-$#@62;SimpleText=""; //定義mouse的類型 Form1-$#@62;Cursor=crDefault ; Edit1-$#@62;Cursor=crDefault; Memo1-$#@62;Cursor=crDefault; Form1-$#@62;Caption ="網路聊天器"; } //--------------------------------------------------------------------------- //用戶端接收資料 void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket) { Memo1-$#@62;Lines-$#@62;Add(Socket-$#@62;ReceiveText()); } //--------------------------------------------------------------------------- //伺服器端接收資料 void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket) { Memo1-$#@62;Lines-$#@62;Add(Socket-$#@62;ReceiveText()); } //--------------------------------------------------------------------------- //在建立連接後,雙方就可以在Edit1中輸入談話內容開始進 //行交談了,按下Enter鍵後,將所在行的文本發送出去 void __fastcall TForm1::Edit1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { AnsiString Data; if(Key==VK_RETURN) {if (Edit2-$#@62;Text!="") //在沒有選擇發送的主機名時不能進行發送操作 {if(IsServer) //伺服器端發出的資料 {Data= "[" TimeToStr(Now()) "]:(" ServerSocket1-$#@62;Socket-$#@62;LocalHost ")對" "(" Edit2-$#@62;Text ")" "說:" Edit1-$#@62;Text; ServerSocket1-$#@62;Socket-$#@62;Connections[TreeView1-$#@62;Selected-$#@62;Index]-$#@62;SendText(Data); Memo1-$#@62;Lines-$#@62;Add(Data); Edit1-$#@62;Text="";} else //用戶端發出的資料 { Data="[" TimeToStr(Now()) "]:(" ClientSocket1-$#@62;Socket-$#@62;LocalHost ")對" "(" Edit2-$#@62;Text ")" "說:" Edit1-$#@62;Text; ClientSocket1-$#@62;Socket-$#@62;SendText(Data); Memo1-$#@62;Lines-$#@62;Add(Data); Edit1-$#@62;Text="";} } else ShowMessage("錯誤!!! 沒有選擇發送的主機名"); } } //--------------------------------------------------------------------------- //在網路中搜索伺服器端時產生的事件 void __fastcall TForm1::ClientSocket1Lookup(TObject *Sender, TCustomWinSocket *Socket) { //定義mouse的類型 Form1-$#@62;Cursor=crHourGlass ; Edit1-$#@62;Cursor=crHourGlass; Memo1-$#@62;Cursor=crHourGlass; } //選擇發向資料的主機名 void __fastcall TForm1::TreeView1Change(TObject *Sender, TTreeNode *Node) { Edit2-$#@62;Text=TreeView1-$#@62;Selected-$#@62;TreeView-$#@62;Selected-$#@62;Text; StatusBar1-$#@62;SimpleText="連接到:" TreeView1-$#@62;Selected-$#@62;TreeView-$#@62;Selected-$#@62;Text; } //監聽 void __fastcall TForm1::BtnlistenClick(TObject *Sender) { ClientSocket1-$#@62;Active=false; ServerSocket1-$#@62;Active=true; StatusBar1-$#@62;SimpleText="正在監聽..."; Form1-$#@62;Caption =Form1-$#@62;Caption "--伺服器端"; Btnlisten-$#@62;Enabled=false; Btnconnect-$#@62;Enabled=false; } //連接 void __fastcall TForm1::BtnconnectClick(TObject *Sender) { if(InputQuery("連接到伺服器","輸入伺服器位址:",Server)) { if(Server.Length() $#@62;0){ ClientSocket1-$#@62;Host=Server; //確定伺服器的主機名 ClientSocket1-$#@62;Active=true; Btnlisten-$#@62;Enabled=false; Btnconnect-$#@62;Enabled=false; Btndisconnect-$#@62;Enabled=true; Form1-$#@62;Caption =Form1-$#@62;Caption "--用戶端";} } } //斷開 void __fastcall TForm1::BtndisconnectClick(TObject *Sender) { //按下斷開 ClientSocket1-$#@62;Close(); } //--------------------------------------------------------------------------- //退出 void __fastcall TForm1::BtnExitClick(TObject *Sender) { ClientSocket1-$#@62;Close(); ServerSocket1-$#@62;Close(); Form1-$#@62;Close(); } //編寫完程式碼後,就要對根源程式進行編譯了,編譯方法如下: 1.在功能表 project \ options 下,選擇Packages 頁,去掉Build with runtime packages 項的勾, 然後選擇Linker 頁,去掉 Use dynamic RTL 的勾,然後按“確定”按鈕。 2.在功能表 project \ options 下,選擇 Compiler 頁,按下 Release 按鈕,然後按“確定”按鈕。 3.在功能表 Run \ Run (或F9) 進行編譯就行。 用這種方法編譯的可執行檔容量比較小, 而且可以在沒有安裝C 的系統中運行。在運行時 可單機也可多機操作,但必須要有一個主機打開程式的“監聽”,其他客戶機進行連接就行了。 快快來下載,編寫自己的聊天程式吧
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-06-01 12:53:58 IP:61.221.xxx.xxx 未訂閱
多謝 bruce0211 版主 幫忙修正 此篇亂碼
系統時間:2024-05-17 5:23:58
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!