string destclient = tokens[3]; for(int n=0; n {
Client cl = (Client)clients[n];
if(cl.Name.CompareTo(tokens[3]) == 0) SendToClient(cl, clientcommand);
if(cl.Name.CompareTo(tokens[1]) == 0) SendToClient(cl, clientcommand); } }
if (tokens[0] == \ {
int remove = 0; bool found = false; int c = clients.Count; for(int n=0; n {
Client cl = (Client)clients[n];
SendToClient(cl, clientcommand);
if(cl.Name.CompareTo(tokens[1]) == 0) {
remove = n; found = true;
lbClients.Items.Remove(cl); } }
if(found)
clients.RemoveAt(remove); client.Close(); keepalive = false; } } } 这样,服务器端程序就基本完成了。(其他略次要的代码可以参见源代码中的Form1.cs文件)程序运行图示如下:
客户端程序:
1. 打开VS.net,新建一个C#的模板为“Windows 应用程序”的项目,不妨命名为“ChatClient”。
2. 布置界面。往界面上添加一个ListBox控件(用于显示用户列表),一个RichTextBox控件(用于显示聊天消息以及系统消息),一个TextBox控件(用于发送消息),一个CheckBox控件(确定是否为悄悄话),一个StatusBar控件以及四个Button控件(分别为“连接”、“断开连接”、“开始记录”、“发送”)。各个控件的属性设置可以参见源代码中的具体设置,这里从略。界面设计好后的图象如下:
3. 客户端程序的代码编写。
当客户端试图和服务器端进行连接时,一个连接必须建立而且得向服务器端进行注册。 EstablishConnection()函数运用一个TcpClient来和服务器端取得连接,同时创建一个NetworkStream来发送消息。还有,端口号和服务器端的是保持一致的,均为5555。EstablishConnection()函数如下:
private void EstablishConnection() {
statusBar1.Text = \正在连接到服务器\ try {
clientsocket = new TcpClient(serveraddress,serverport); ns = clientsocket.GetStream(); sr = new StreamReader(ns); connected = true; }
catch (Exception) {
MessageBox.Show(\不能连接到服务器!\错误\
MessageBoxButtons.OK, MessageBoxIcon.Exclamation); statusBar1.Text = \已断开连接\ } }
在和服务器端连接成功后,程序就用RegisterWithServer()函数向服务器端发送一个CONN命令。该命令先是发送该用户的名称,然后从服务器端获得其他所有用户的列表,所有用户列表是在ListBox控件中显示的。该函数如下:
private void RegisterWithServer() { try {
string command = \
Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray()); ns.Write(outbytes,0,outbytes.Length);
string serverresponse = sr.ReadLine(); serverresponse.Trim();
string[] tokens = serverresponse.Split(new Char[]{'|'}); if(tokens[0] == \ {
statusBar1.Text = \已连接\ btnDisconnect.Enabled = true; }
for(int n=1; n
lbChatters.Items.Add(tokens[n].Trim(new char[]{'\\r','\\n'})); this.Text = clientname + \:已连接到服务器\ }
catch (Exception) {
MessageBox.Show(\注册时发生错误!\错误\
MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
在此之后,当然就是用户之间的聊天了,由ReceiveChat()函数来完成。该函数是一个独立的线程,它处理所有用户获得的消息和用户发送的消息。它主要处理了CHAT、PRIV、JOIN、GONE、QU99v等命令,处理的方法和服务器端的类似。具体函数实现如下:
private void ReceiveChat() {
bool keepalive = true; while (keepalive) { try {
Byte[] buffer = new Byte[2048]; ns.Read(buffer,0,buffer.Length);
string chatter = System.Text.Encoding.ASCII.GetString(buffer); string[] tokens = chatter.Split(new Char[]{'|'});
if (tokens[0] == \ {
rtbChatIn.AppendText(tokens[1]); if(logging)
logwriter.WriteLine(tokens[1]); }
if (tokens[0] == \ {
rtbChatIn.AppendText(\ rtbChatIn.AppendText(tokens[1].Trim() ); rtbChatIn.AppendText(tokens[2] + \ if(logging) {
logwriter.Write(\ logwriter.Write(tokens[1].Trim() ); logwriter.WriteLine(tokens[2] + \ } }
if (tokens[0] == \ {
rtbChatIn.AppendText(tokens[1].Trim() );
rtbChatIn.AppendText(\ if(logging) {
logwriter.WriteLine(tokens[1]+\ }
string newguy = tokens[1].Trim(new char[]{'\\r','\\n'}); lbChatters.Items.Add(newguy); }
if (tokens[0] == \ {
rtbChatIn.AppendText(tokens[1].Trim() );
rtbChatIn.AppendText(\ if(logging) {
logwriter.WriteLine(tokens[1]+\ }
lbChatters.Items.Remove(tokens[1].Trim(new char[]{'\\r','\\n'})); }
if (tokens[0] == \ {
ns.Close();
clientsocket.Close();