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 }