C#编写聊天软件客户端

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using System.Net.Sockets;
 10 using System.Net;
 11 using System.IO;
 12 using System.Threading;
 13 
 14 namespace SyncChatClient
 15 {
 16     public partial class MainForm : Form
 17     {
 18         private string ServerIP; //IP
 19         private int port;   //端口
 20         private bool isExit = false;
 21         private TcpClient client;
 22         private BinaryReader br;
 23         private BinaryWriter bw;
 24         public MainForm()
 25         {
 26             InitializeComponent();
 27             Random r = new Random((int)DateTime.Now.Ticks);
 28             txt_UserName.Text = "user" + r.Next(100, 999);
 29             lst_OnlineUser.HorizontalScrollbar = true;
 30             SetServerIPAndPort();
 31         }
 32 
 33         /// <summary>
 34         /// 根据当前程序目录的文本文件‘ServerIPAndPort.txt’内容来设定IP和端口
 35         /// 格式:127.0.0.1:8885
 36         /// </summary>
 37         private void SetServerIPAndPort()
 38         {
 39             try
 40             {
 41                 FileStream fs = new FileStream("ServerIPAndPort.txt", FileMode.Open);
 42                 StreamReader sr = new StreamReader(fs);
 43                 string IPAndPort = sr.ReadLine();
 44                 ServerIP = IPAndPort.Split(':')[0]; //设定IP
 45                 port = int.Parse(IPAndPort.Split(':')[1]); //设定端口
 46                 sr.Close();
 47                 fs.Close();
 48             }
 49             catch (Exception ex)
 50             {
 51                 MessageBox.Show("配置IP与端口失败,错误原因:" + ex.Message);
 52                 Application.Exit();
 53             }
 54         }
 55 
 56         /// <summary>
 57         /// 【登陆】按钮事件
 58         /// </summary>
 59         /// <param name="sender"></param>
 60         /// <param name="e"></param>
 61         private void btn_Login_Click(object sender, EventArgs e)
 62         {
 63             btn_Login.Enabled = false;
 64             try
 65             {
 66                 //此处为方便演示,实际使用时要将Dns.GetHostName()改为服务器域名
 67                 //IPAddress ipAd = IPAddress.Parse("182.150.193.7");
 68                 client = new TcpClient();
 69                 client.Connect(IPAddress.Parse(ServerIP), port);
 70                 AddTalkMessage("连接成功");
 71             }
 72             catch(Exception ex)
 73             {
 74                 AddTalkMessage("连接失败,原因:" + ex.Message);
 75                 btn_Login.Enabled = true;
 76                 return;
 77             }
 78             //获取网络流
 79             NetworkStream networkStream = client.GetStream();
 80             //将网络流作为二进制读写对象
 81             br = new BinaryReader(networkStream);
 82             bw = new BinaryWriter(networkStream);
 83             SendMessage("Login," + txt_UserName.Text);
 84             Thread threadReceive = new Thread(new ThreadStart(ReceiveData));
 85             threadReceive.IsBackground = true;
 86             threadReceive.Start();
 87         }
 88 
 89         /// <summary>
 90         /// 处理服务器信息
 91         /// </summary>
 92         private void ReceiveData()
 93         {
 94             string receiveString = null;
 95             while (isExit == false)
 96             {
 97                 try
 98                 {
 99                     //从网络流中读出字符串
100                     //此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串
101                     receiveString = br.ReadString();
102                 }
103                 catch
104                 {
105                     if (isExit == false)
106                     {
107                         MessageBox.Show("与服务器失去连接");
108                     }
109                     break;
110                 }
111                 string[] splitString = receiveString.Split(',');
112                 string command = splitString[0].ToLower();
113                 switch (command)
114                 {
115                     case "login":   //格式: login,用户名
116                         AddOnline(splitString[1]);
117                         break;
118                     case "logout":  //格式: logout,用户名
119                         RemoveUserName(splitString[1]);
120                         break;
121                     case "talk":    //格式: talk,用户名,对话信息
122                         AddTalkMessage(splitString[1] + ":\r\n");
123                         AddTalkMessage(receiveString.Substring(splitString[0].Length + splitString[1].Length+2));
124                         break;
125                     default:
126                         AddTalkMessage("什么意思啊:" + receiveString);
127                         break;
128                 }
129             }
130             Application.Exit();
131         }
132 
133         /// <summary>
134         /// 向服务端发送消息
135         /// </summary>
136         /// <param name="message"></param>
137         private void SendMessage(string message)
138         {
139             try
140             {
141                 //将字符串写入网络流,此方法会自动附加字符串长度前缀
142                 bw.Write(message);
143                 bw.Flush();
144             }
145             catch
146             {
147                 AddTalkMessage("发送失败");
148             }
149         }
150 
151         private delegate void AddTalkMessageDelegate(string message);
152         /// <summary>
153         /// 在聊天对话框(txt_Message)中追加聊天信息
154         /// </summary>
155         /// <param name="message"></param>
156         private void AddTalkMessage(string message)
157         {
158             if (txt_Message.InvokeRequired)
159             {
160                 AddTalkMessageDelegate d = new AddTalkMessageDelegate(AddTalkMessage);
161                 txt_Message.Invoke(d, new object[] { message });
162             }
163             else
164             {
165                 txt_Message.AppendText(message + Environment.NewLine);
166                 txt_Message.ScrollToCaret();
167             }
168         }
169 
170         private delegate void AddOnlineDelegate(string message);
171         /// <summary>
172         /// 在在线框(lst_Online)中添加其他客户端信息
173         /// </summary>
174         /// <param name="userName"></param>
175         private void AddOnline(string userName)
176         {
177             if (lst_OnlineUser.InvokeRequired)
178             {
179                 AddOnlineDelegate d = new AddOnlineDelegate(AddOnline);
180                 lst_OnlineUser.Invoke(d, new object[] { userName });
181             }
182             else
183             {
184                 lst_OnlineUser.Items.Add(userName);
185                 lst_OnlineUser.SelectedIndex = lst_OnlineUser.Items.Count - 1;
186                 lst_OnlineUser.ClearSelected();
187             }
188         }
189 
190         private delegate void RemoveUserNameDelegate(string userName);
191         /// <summary>
192         /// 在在线框(lst_Online)中移除不在线的客户端信息
193         /// </summary>
194         /// <param name="userName"></param>
195         private void RemoveUserName(string userName)
196         {
197             if (lst_OnlineUser.InvokeRequired)
198             {
199                 RemoveUserNameDelegate d = new RemoveUserNameDelegate(RemoveUserName);
200                 lst_OnlineUser.Invoke(d, userName);
201             }
202             else
203             {
204                 lst_OnlineUser.Items.Remove(userName);
205                 lst_OnlineUser.SelectedIndex = lst_OnlineUser.Items.Count - 1;
206                 lst_OnlineUser.ClearSelected();
207             }
208         }
209 
210         /// <summary>
211         /// 【发送】按钮单击事件
212         /// </summary>
213         /// <param name="sender"></param>
214         /// <param name="e"></param>
215         private void btn_Send_Click(object sender, EventArgs e)
216         {
217             if (lst_OnlineUser.SelectedIndex != -1)
218             {
219                 SendMessage("Talk," + lst_OnlineUser.SelectedItem + "," + txt_SendText.Text + "\r\n");
220                 txt_SendText.Clear();
221             }
222             else
223             {
224                 MessageBox.Show("请先在【当前在线】中选择一个对话着");
225             }
226         }
227 
228         /// <summary>
229         /// 窗体关闭事件
230         /// </summary>
231         /// <param name="sender"></param>
232         /// <param name="e"></param>
233         private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
234         {
235             //未与服务器连接前 client 为 null
236             if (client != null)
237             {
238                 try
239                 {
240                     SendMessage("Logout," + txt_UserName.Text);
241                     isExit = true;
242                     br.Close();
243                     bw.Close();
244                     client.Close();
245                 }
246                 catch
247                 {
248                 }
249             }
250         }
251 
252         /// <summary>
253         /// 在发送信息的文本框中按下【Enter】键触发的事件
254         /// </summary>
255         /// <param name="sender"></param>
256         /// <param name="e"></param>
257         private void txt_SendText_KeyPress(object sender, KeyPressEventArgs e)
258         {
259             if (e.KeyChar == (char)Keys.Return)
260             {
261                 //触发【发送】按钮的单击事件
262                 btn_Send.PerformClick();
263             }
264         }
265 
266         private void btn_LoadOnlineUser_Click(object sender, EventArgs e)
267         {
268 
269         }
270 
271 
272     }
273 }