客戶端程序:
1.打開VS.net,用C#中的“Windows應用程序”模板新建壹個項目,可以命名為“ChatClient”。
2.布局界面。在界面中添加壹個ListBox控件(用於顯示用戶列表)、壹個RichTextBox控件(用於顯示聊天消息和系統消息)、壹個TextBox控件(用於發送消息)、壹個CheckBox控件(用於確定是否是悄悄話)、壹個StatusBar控件和四個按鈕控件(分別為連接、斷開、開始記錄和發送)。各控件的屬性設置請參考源代碼中的具體設置,此處不再贅述。
3.客戶端程序的代碼編寫。
當客戶端嘗試與服務器連接時,必須建立連接並向服務器註冊。EstablishConnection()函數使用TcpClient連接服務器,並創建NetworkStream來發送消息。還有,端口號和服務器端的壹樣,都是5555。EstablishConnection()函數如下:
私有void EstablishConnection()
{
StatusBar1。Text = "連接到服務器";
嘗試
{
client socket = new TCP client(server address,server port);
ns =客戶端套接字。GetStream();
sr =新StreamReader(ns);
連接=真;
}
捕捉(異常)
{
MessageBox。Show("無法連接到服務器!",“錯誤”,
MessageBoxButtons好了,MessageBoxIcon。感嘆);
StatusBar1。Text = "斷開連接";
}
}
成功連接服務器後,程序使用RegisterWithServer()函數向服務器發送conn命令。該命令首先發送用戶名,然後從服務器獲取所有其他用戶的列表,所有用戶列表都顯示在ListBox控件中。該功能如下所示:
私有void RegisterWithServer()
{
嘗試
{
string command = "CONN|" + ChatOut。文本;
Byte[] outbytes = System。Text.Encoding.ASCII.GetBytes(命令。ToCharArray());
ns。寫(outbytes,0,outbytes。長度);
string server response = Sr . ReadLine();
服務器響應。trim();
string[]token = server response。split(new Char[]{ ' | ' });
if(tokens[0] == "LIST ")
{
StatusBar1。Text = "已連接";
btnDisconnect。Enabled = true
}
for(int n = 1;n
lbChatters。Items.Add(tokens[n].Trim(new char[]{'\r ',' \ n ' });
這個。Text = clientname+":已連接到服務器";
}
捕捉(異常)
{
MessageBox。顯示("註冊錯誤!",“錯誤”,
MessageBoxButtons好了,MessageBoxIcon。感嘆);
}
}
之後當然是用戶之間的聊天,由ReceiveChat()函數完成。這個函數是壹個獨立的線程,處理用戶獲取的所有消息和用戶發送的消息。主要處理聊天、PRIV、加入、離開、退出等命令。,處理方式與服務器端類似。具體功能實現如下:
私有void ReceiveChat()
{
bool keepalive = true
while(保持活動)
{
嘗試
{
Byte[] buffer =新字節[2048];
ns。讀取(buffer,0,buffer。長度);
弦顫=系統。text . encoding . ascii . getstring(buffer);
string[]token = chatter。split(new Char[]{ ' | ' });
if (tokens[0] == "CHAT ")
{
rtbChatIn。append text(tokens[1]);
如果(記錄)
日誌作者。WriteLine(tokens[1]);
}
if(token[0]= = " PRIV ")
{
rtbChatIn。AppendText(" Private from ");
rtbChatIn。AppendText(tokens[1]。trim());
rtbChatIn。append text(tokens[2]+" \ r \ n ");
如果(記錄)
{
日誌作者。寫(“私從”);
日誌作者。寫(令牌[1])。trim());
日誌作者。WriteLine(tokens[2]+" \ r \ n ");
}
}
if (tokens[0] == "JOIN ")
{
rtbChatIn。AppendText(tokens[1]。trim());
rtbChatIn。AppendText("已加入聊天\ r \ n ");
如果(記錄)
{
日誌作者。WriteLine(tokens[1]+"已加入聊天));
}
string newguy = tokens[1]。Trim(new char[]{'\r ',' \ n ' });
lbChatters。items . Add(new guy);
}
if (tokens[0] == "消失")
{
rtbChatIn。AppendText(tokens[1]。trim());
rtbChatIn。AppendText("已離開聊天\ r \ n ");
如果(記錄)
{
日誌作者。WriteLine(tokens[1]+"已離開聊天);
}
lbChatters。Items.Remove(tokens[1])。Trim(new char[]{'\r ',' \ n ' });
}
if (tokens[0] == "QUIT ")
{
ns。close();
客戶端套接字。close();
keepalive = false
StatusBar1。Text = "服務器已停止";
連通=假;
btnSend。Enabled = false
btnDisconnect。Enabled = false
}
}
catch(異常){}
}
}
通過以上功能,客戶端程序可以自由聊天,用戶也可以互相發送密語。所以程序實現了聊天室的基本功能,但是最後所有用戶都要正常退出,所以會用到QuitChat()函數。該功能的具體實現如下:
私有void QuitChat()
{
如果(已連接)
{
嘗試
{
string command = " GONE | "+client name;
Byte[] outbytes = System。Text.Encoding.ASCII.GetBytes(命令。ToCharArray());
ns。寫(outbytes,0,outbytes。長度);
客戶端套接字。close();
}
捕捉(異常)
{
}
}
如果(記錄)
日誌作者。close();
如果(收到!= null & amp& amp收到。IsAlive)
收到。abort();
這個。Text = " client
}
到目前為止,已經介紹了客戶端程序的主要部分。還有壹些按鈕控件的消息處理函數,可以在源代碼中找到。同時程序中還有聊天記錄功能,類似於現在流行的聊天軟件的記錄功能。不過限於篇幅,這裏就不壹壹介紹了。感興趣的讀者可以研究壹下本文後面的源代碼。
這樣,客戶端程序就完成了。程序運行圖如下:
總結:
介紹了socket的基本概念和socket編程的基本原理,並通過壹個很好的例子向大家展示了C#下socket編程的實現方法和壹些編程技巧。由此我們不難發現,使用C#進行socket編程甚至網絡編程有很多好處。示例程序的思想清晰易懂,是壹個很好的例子。希望妳能好好學習。同時,我希望妳能進壹步改進程序,使它更加強大和友好。