Socket聊天室-TcpListener,TcpClient

参考自:http://blog.csdn.net/liguo9860/article/details/6148614

服务端:

  1         #region 属性
  2
  3         //请求的客户端连接
  4         Socket clientsocket;
  5         //当前连接集合
  6         List<Client> clients;
  7         //请求客户端线程
  8         Thread clientservice;
  9         //服务器监听线程
 10         Thread threadListen;
 11         //服务器监听连接
 12         TcpListener listener;
 13         //本机ip地址
 14         IPAddress currentIp;
 15         //端口号
 16         Int32 currentPort;
 17
 18         public delegate void MyInvoke(string str);
 19
 20         #endregion
 21
 22         #region 自定义事件
 23
 24         /// <summary>
 25         /// 开始监听
 26         /// </summary>
 27         public void StartListening()
 28         {
 29             //本机ip
 30             currentIp = GetIPAddress();
 31             //使用端口号
 32             currentPort = int.Parse(nudPort.Value.ToString());
 33             //定义网络连接监听
 34             listener = new TcpListener(currentIp, currentPort);
 35             listener.Start();
 36             while (true)
 37             {
 38                 try
 39                 {
 40                     //开始监听网络连接
 41                     clientsocket = listener.AcceptSocket();
 42                     //客户端连接线程
 43                     clientservice = new Thread(new ThreadStart(ServiceClient));
 44                     clientservice.IsBackground = true;
 45                     //启用线程
 46                     clientservice.Start();
 47                 }
 48                 catch (Exception ex)
 49                 {
 50                     //创建设置状态文本线程
 51                     Thread handlerControl = new Thread(delegate() { setErrorText(ex.Message); });
 52                     //启动线程
 53                     handlerControl.Start();
 54                 }
 55             }
 56         }
 57
 58         /// <summary>
 59         /// 客户端服务
 60         /// </summary>
 61         public void ServiceClient()
 62         {
 63             //获取一个客户端连接
 64             Socket client = clientsocket;
 65             //用于标识连接是否存活
 66             Boolean keepalive = true;
 67             //判断新连接是否存在
 68             if (client == null)
 69             {
 70                 keepalive = false;
 71             }
 72             else
 73             {
 74                 keepalive = true;
 75             }
 76
 77             //客户端连接存活
 78             while (keepalive)
 79             {
 80                 //数据字节
 81                 Byte[] buffer = new Byte[1024];
 82                 //数据量
 83                 int bufLen = 0;
 84                 try
 85                 {
 86                     //获取从客户端获取的数据量
 87                     bufLen = client.Available;
 88                     //无数据,再监听
 89                     if (bufLen < 1)
 90                     {
 91                         continue;
 92                     }
 93
 94                     //有数据,接受客户端发送的数据
 95                     client.Receive(buffer, 0, bufLen, SocketFlags.None);
 96
 97                     //将字节数组转为字符串
 98                     string infoStr = Encoding.UTF8.GetString(buffer).Substring(0, bufLen).Trim(new char[] { ‘\r‘, ‘\0‘ });
 99
100                     //显示在消息框
101                     setText(infoStr);
102
103                     //分割传入的信息
104                     string[] infoArr = infoStr.Split(‘|‘);
105                     //消息类型
106                     string type = infoArr[0];
107
108                     //CONN:表示新建连接。发送格式:CONN|发送者名称
109                     if (type == "CONN")
110                     {
111                         //是否重复
112                         bool isRepeat = false;
113                         //循环所有在线看账号是否重复
114                         foreach (Client item in clients)
115                         {
116                             if (infoArr[1].Trim() == item.Name.Trim())
117                             {
118                                 //如果还在连接状态
119                                 if (client.Connected)
120                                 {
121                                     //发送消息
122                                     sendToClient(new Client("", null, null, client), "ERROR|账号重复");
123                                     isRepeat = true;
124                                 }
125                                 break;
126                             }
127                         }
128
129                         //重复了,重新监听
130                         if (isRepeat)
131                         {
132                             keepalive = false;
133                             continue;
134                         }
135
136                         //循环所有在线连接
137                         foreach (Client item in clients)
138                         {
139                             //向所有在线连接发送当前连接加入消息
140                             sendToClient(item, "JOIN|" + infoArr[1]);
141                         }
142
143                         //新连接的网络地址
144                         EndPoint ep = client.RemoteEndPoint;
145                         //新建一个客户端连接
146                         Client newCl = new Client(infoArr[1], ep, clientservice, client);
147                         //添加到在线列表中
148                         clients.Add(newCl);
149
150                         //向新连接发送在线列表
151                         sendToClient(newCl, "LIST|" + getChatterList());
152
153                         //将新连接添加到服务器当前连接列表中
154                         new Thread(delegate() { handerListBox(string.Format("{0}|{1}", newCl.Name, newCl.ClHost.ToString()), "add"); }).Start();
155                     }
156
157                     //CHAT:发送全局消息,所有其他连接都可以接收到。发送格式:CHAT|发送者名称|信息内容
158                     if (type == "CHAT")
159                     {
160                         //找出所有在线连接并发送消息
161                         foreach (Client item in clients)
162                         {
163                             //发送消息
164                             sendToClient(item, infoStr);
165                         }
166                     }
167
168                     //PRIV:发送私聊信息。发送格式:PRIV|发送者名称|信息内容|接受者名称
169                     if (type == "PRIV")
170                     {
171                         //找出接受者和发送者发送消息
172                         foreach (Client item in clients)
173                         {
174                             //如果是接受者或者是发送者
175                             if (item.Name == infoArr[1] || item.Name == infoArr[3])
176                             {
177                                 //发送消息
178                                 sendToClient(item, infoStr);
179                             }
180                         }
181                     }
182
183                     //GONE 退出。发送格式:GONE|发送者名称
184                     if (type == "GONE")
185                     {
186                         //是否存在
187                         bool found = false;
188                         //连接名称
189                         string clientname = "";
190                         //在在线集合中索引
191                         int index = 0;
192                         int i = 0;
193
194                         //循环所有连接
195                         foreach (Client item in clients)
196                         {
197                             //如果是退出者
198                             if (item.Name == infoArr[1])
199                             {
200                                 //发送确认退出信息
201                                 sendToClient(item, "QUIT|");
202                                 //获取连接名称
203                                 clientname = item.Name + "|" + item.ClHost.ToString();
204                                 found = true;
205                                 index = i;
206                             }
207                             //不是退出者
208                             else
209                             {
210                                 //发送消息
211                                 sendToClient(item, infoStr);
212                             }
213                             i++;
214                         }
215
216                         //已退出
217                         if (found)
218                         {
219                             //创建从服务器在线列表移除退出连接线程
220                             new Thread(delegate() { delItem(clientname); }).Start();
221                             //从集合中删除连接
222                             clients.RemoveAt(index);
223                             //改变存活状态
224                             keepalive = false;
225                         }
226                     }
227
228                 }
229                 catch (Exception ex)
230                 {
231                     //创建设置状态文本线程
232                     new Thread(delegate() { setErrorText(ex.Message); }).Start();
233                     keepalive = false;
234                 }
235             }
236         }
237
238         /// <summary>
239         /// 发送消息到客户端
240         /// </summary>
241         /// <param name="cl">客户端</param>
242         /// <param name="msg">要发送的消息,其中包含了消息类型</param>
243         private void sendToClient(Client cl, string msg)
244         {
245             //将消息转为字节数组
246             Byte[] byMsg = Encoding.UTF8.GetBytes(msg);
247             //获取客户端连接
248             Socket clSocket = cl.ClSock;
249             //如果还在连接状态
250             if (clSocket.Connected)
251             {
252                 //发送消息
253                 clSocket.Send(byMsg, byMsg.Length, 0);
254             }
255         }
256
257         /// <summary>
258         /// 输出信息
259         /// </summary>
260         /// <param name="msg">信息文本</param>
261         private void setText(string msg)
262         {
263             //不是当前线程调用
264             if (rtbInfo.InvokeRequired)
265             {
266                 MyInvoke _myInvoke = new MyInvoke(setText);
267                 Invoke(_myInvoke, new object[] { msg });
268             }
269             else
270             {
271                 rtbInfo.AppendText(string.Format("\n{0} {1}", msg, DateTime.Now));
272             }
273         }
274
275         /// <summary>
276         /// 输出错误信息
277         /// </summary>
278         /// <param name="msg">信息文本</param>
279         private void setErrorText(string msg)
280         {
281             //不是当前线程调用
282             if (rtbInfo.InvokeRequired)
283             {
284                 MyInvoke _myInvoke = new MyInvoke(setErrorText);
285                 Invoke(_myInvoke, new object[] { msg });
286             }
287             else
288             {
289                 rtbError.AppendText(string.Format("\n异常:{0} {1}", msg, DateTime.Now));
290             }
291         }
292
293         /// <summary>
294         /// 添加或删除当前连接客户端
295         /// </summary>
296         /// <param name="c">客户端信息</param>
297         /// <param name="o">操作</param>
298         private void handerListBox(string c, string o)
299         {
300             //如果是其他线程调用
301             if (lbClients.InvokeRequired)
302             {
303                 //委托
304                 MyInvoke _myInvoke;
305                 //要执行的操作
306                 if (o == "add")
307                 {
308                     _myInvoke = new MyInvoke(addItem);
309                 }
310                 else
311                 {
312                     _myInvoke = new MyInvoke(delItem);
313                 }
314                 Invoke(_myInvoke, new object[] { c });
315             }
316         }
317
318         /// <summary>
319         /// 在当前连接列表中删除一个连接
320         /// </summary>
321         /// <param name="c"></param>
322         private void delItem(string c)
323         {
324             this.lbClients.Items.Remove(c);
325         }
326
327         /// <summary>
328         /// 在当前连接列表中新建一个连接
329         /// </summary>
330         /// <param name="c"></param>
331         private void addItem(string c)
332         {
333             this.lbClients.Items.Add(c);
334         }
335
336         /// <summary>
337         /// 获取当前连接集合
338         /// </summary>
339         /// <returns></returns>
340         private string getChatterList()
341         {
342             StringBuilder sb = new StringBuilder();
343             foreach (Client item in clients)
344             {
345                 sb.Append(item.Name);
346                 sb.Append("|");
347             }
348
349             return sb.Length > 0 ? sb.ToString().TrimEnd(‘|‘) : "";
350         }
351
352         /// <summary>
353         /// 获取本机ip
354         /// </summary>
355         /// <returns></returns>
356         private IPAddress GetIPAddress()
357         {
358             String hostName = Dns.GetHostName();
359             IPAddress[] myIP = Dns.GetHostAddresses(hostName);
360             foreach (IPAddress address in myIP)
361             {
362                 if (address.AddressFamily.ToString() == "InterNetwork")
363                 {
364                     return address;
365                 }
366             }
367             return IPAddress.None;
368         }
369
370         /// <summary>
371         /// 端口是否被占用
372         /// </summary>
373         /// <param name="port"></param>
374         /// <returns></returns>
375         private static bool portInUse(int port)
376         {
377             bool inUse = false;
378             IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
379             IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
380
381             foreach (IPEndPoint endPoint in ipEndPoints)
382             {
383                 if (endPoint.Port == port)
384                 {
385                     inUse = true;
386                     break;
387                 }
388             }
389             return inUse;
390         }
391
392         #endregion
393
394         #region 页面Load事件
395
396         private void ServerForm_Load(object sender, EventArgs e)
397         {
398             //实例化当前连接集合
399             clients = new List<Client>();
400             lblAdress.Text = GetIPAddress().ToString();
401         }
402
403         #endregion
404
405         #region 页面控件事件
406         private void btnStart_Click(object sender, EventArgs e)
407         {
408             try { int.Parse(nudPort.Value.ToString()); }
409             catch { MessageBox.Show("端口号错误!"); return; }
410             if (portInUse(int.Parse(nudPort.Value.ToString())))
411             {
412                 MessageBox.Show("该端口号已被占用!");
413                 return;
414             }
415
416             btnStart.Enabled = false;
417             try
418             {
419                 //创建监听线程
420                 threadListen = new Thread(StartListening);
421                 threadListen.IsBackground = true;
422                 //启动线程
423                 threadListen.Start();
424                 //创建设置状态文本线程
425                 new Thread(delegate() { setText("服务器正在监听..."); }).Start();
426                 lblRunTime.Text = DateTime.Now.ToString();
427             }
428             catch (Exception ex)
429             {
430                 //创建设置状态文本线程
431                 new Thread(delegate() { setErrorText(ex.Message); }).Start();
432             }
433         }
434
435         private void ServerForm_FormClosed(object sender, FormClosedEventArgs e)
436         {
437             if (clients != null) clients.Clear();
438             if (listener != null) listener.Stop();
439             if (threadListen != null && threadListen.IsAlive) threadListen.Abort();
440             GC.Collect();
441             GC.WaitForPendingFinalizers();
442         }
443
444         private void rtbInfo_TextChanged(object sender, EventArgs e)
445         {
446             rtbInfo.ScrollToCaret();
447         }
448
449         private void rtbError_TextChanged(object sender, EventArgs e)
450         {
451             rtbError.ScrollToCaret();
452         }
453
454         #endregion

客户端:

  1         #region 属性
  2
  3         //NetWorkStream
  4         NetworkStream ns;
  5         //数据流
  6         StreamReader sr;
  7         //客户端连接
  8         TcpClient clientsocket;
  9         //是否连接
 10         Boolean connected;
 11         //接受信息线程
 12         Thread receive;
 13         //服务器网络地址
 14         String serveraddress = "192.168.1.45";
 15         //服务器端口号
 16         Int32 serverport = 8888;
 17         //客户端连接名称
 18         String clientname;
 19         //实现操纵其他线程委托
 20         public delegate void MyInvoke(string c);
 21
 22         #endregion
 23
 24         #region 自定义事件
 25
 26         /// <summary>
 27         /// 连接到服务器(连接端口)
 28         /// </summary>
 29         public void EstablishConnection()
 30         {
 31             //设置状态栏
 32             setState("正在连接到服务器...");
 33             try
 34             {
 35                 //根据网络地址和端口号获取服务器连接
 36                 clientsocket = new TcpClient(serveraddress, serverport);
 37                 //获取发送和接受数据的NetWorkStream
 38                 ns = clientsocket.GetStream();
 39                 //为NetworkStream 初始化StreamReader实例
 40                 sr = new StreamReader(ns);
 41                 //连接成功
 42                 connected = true;
 43             }
 44             catch (Exception ex)
 45             {
 46                 setErrorText(ex.Message);
 47                 setState("连接出错,连接已断开!");
 48             }
 49         }
 50
 51         /// <summary>
 52         /// 注册到服务器(注册数据)
 53         /// </summary>
 54         public void RegisterWithServer()
 55         {
 56             //获取用户名
 57             clientname = txtAccount.Text.Trim();
 58             //清空当前连接列表
 59             lbClients.Items.Clear();
 60
 61             try
 62             {
 63                 //消息内容
 64                 string command = "CONN|" + clientname;
 65                 //转为字节数组
 66                 Byte[] byMsg = Encoding.UTF8.GetBytes(command.ToCharArray());
 67                 //写入流
 68                 ns.Write(byMsg, 0, byMsg.Length);
 69                 //接受消息数组
 70                 Byte[] byInfo = new Byte[1024];
 71                 //读取数据到数组
 72                 ns.Read(byInfo, 0, byInfo.Length);
 73                 //转为字符串
 74                 string returnInfo = Encoding.UTF8.GetString(byInfo).Trim(new char[] { ‘\0‘, ‘\r‘ }).TrimEnd(‘|‘);
 75                 //分割出信息
 76                 string[] infoArr = returnInfo.Split(‘|‘);
 77                 //LIST:返回所有连接到服务器的客户端连接。发送格式:LIST|客户端名称|客户端名称|...
 78                 if (infoArr[0] == "LIST")
 79                 {
 80                     //加入连接列表
 81                     for (int i = 1; i < infoArr.Length; i++)
 82                     {
 83                         //将信息逐条添加到列表中
 84                         lbClients.Items.Add(infoArr[i].Trim());
 85                     }
 86                     //改变状态栏信息
 87                     setState(string.Format("{0}已连接到服务器!", clientname));
 88
 89                     //改变页面控件状态
 90                     txtAccount.Enabled = false;
 91                     btnLink.Enabled = false;
 92                     btnSendMsg.Enabled = true;
 93                 }
 94
 95                 //ERROR:错误消息
 96                 if (infoArr[0] == "ERROR")
 97                 {
 98                     //断开连接
 99                     connected = false;
100                     //改变页面控件状态
101                     txtAccount.Enabled = true;
102                     btnLink.Enabled = true;
103                     btnSendMsg.Enabled = false;
104                     throw new Exception(infoArr[1]);
105                 }
106             }
107             catch (Exception ex)
108             {
109                 setErrorText(ex.Message);
110                 setState("注册出错,连接已断开!");
111                 connected = false;
112             }
113         }
114
115         /// <summary>
116         /// 接受服务器消息
117         /// </summary>
118         public void ReceiveChat()
119         {
120             //保持连接状态
121             bool keepalive = true;
122             while (keepalive)
123             {
124                 try
125                 {
126                     //接受消息数组
127                     Byte[] byInfo = new Byte[1024];
128                     //读取数据到数组
129                     ns.Read(byInfo, 0, byInfo.Length);
130                     //转为字符串
131                     string infoStr = Encoding.UTF8.GetString(byInfo).Trim(new char[] { ‘\r‘, ‘\0‘ }).TrimEnd(‘|‘);
132                     //分割
133                     string[] infoArr = infoStr.Split(‘|‘);
134                     //消息类型
135                     string type = infoArr[0];
136
137                     //CHAT:是否为群发消息
138                     if (type == "CHAT")
139                     {
140                         //显示消息
141                         new Thread(delegate()
142                         {
143                             setText(string.Format("{0}:{1}", infoArr[1], infoArr[2].Trim()));
144                         }).Start();
145                     }
146
147                     //PRIV:是否为私聊消息
148                     if (type == "PRIV")
149                     {
150                         //在消息面板上显示:信息来自
151                         new Thread(delegate()
152                         {
153                             setText(string.Format("来自【{0}】的私信:{1}", infoArr[1], infoArr[2].Trim()));
154                         }).Start();
155                     }
156
157                     //JOIN:是否添加新连接消息
158                     if (type == "JOIN")
159                     {
160                         //显示加入消息并添加到当前在线连接
161                         new Thread(delegate()
162                         {
163                             setText(string.Format("【{0}】加入房间!", infoArr[1].Trim()));
164                             handerListBox(infoArr[1].Trim(new char[] { ‘\r‘, ‘\n‘ }), "add");
165                         }).Start();
166                     }
167
168                     //GONE:是否为退出消息
169                     if (type == "GONE")
170                     {
171                         //显示加入消息并添加到当前在线连接
172                         new Thread(delegate()
173                         {
174                             setText(string.Format("【{0}】离开房间!", infoArr[1].Trim()));
175                             handerListBox(infoArr[1].Trim(), "del");
176                         }).Start();
177                     }
178
179                     //QUIT:此客户端退出
180                     if (type == "QUIT")
181                     {
182                         //停止接收消息
183                         keepalive = false;
184                         //提示消息线程
185                         new Thread(delegate() { setState("连接已断开"); }).Start();
186                         //断开连接
187                         connected = false;
188                     }
189                 }
190                 catch (Exception ex)
191                 {
192                     setErrorText(ex.Message);
193                     keepalive = false;
194                 }
195             }
196
197             //判断线程是否为活动的
198             if (!connected && receive != null && receive.IsAlive)
199                 //如果是则中止线程
200                 receive.Abort();
201         }
202
203         /// <summary>
204         /// 退出服务器端
205         /// </summary>
206         public void QuitChat()
207         {
208             //判断是否为连接状态
209             if (connected)
210             {
211                 try
212                 {
213                     //创建消息
214                     string command = "GONE|" + clientname;
215                     //将消息转化为字节流
216                     Byte[] outbytes = Encoding.UTF8.GetBytes(command.ToCharArray());
217                     //将消息发送给NetWorkStream
218                     ns.Write(outbytes, 0, outbytes.Length);
219                 }
220                 catch (Exception e)
221                 {
222                     setErrorText(e.Message);
223                 }
224             }
225             if (receive != null && receive.IsAlive) receive.Abort();
226             if (ns != null) { ns.Close(); ns.Dispose(); }
227             if (sr != null) { sr.Close(); sr.Dispose(); }
228             if (clientsocket != null) clientsocket.Close();
229             GC.Collect();
230             GC.WaitForPendingFinalizers();
231         }
232
233         /// <summary>
234         /// 操作当前连接列表
235         /// </summary>
236         /// <param name="c">客户端信息</param>
237         /// <param name="o">操作</param>
238         private void handerListBox(string c, string o)
239         {
240             //判断是否是创建控件的线程调用
241             if (this.lbClients.InvokeRequired)
242             {
243                 //创建委托
244                 MyInvoke invoke;
245                 if (o == "add")
246                     invoke = new MyInvoke(addItem);
247                 else
248                     invoke = new MyInvoke(delItem);
249                 //执行委托
250                 Invoke(invoke, new object[] { c });
251             }
252         }
253         /// <summary>
254         /// 添加连接
255         /// </summary>
256         /// <param name="c"></param>
257         private void addItem(string c)
258         {
259             this.lbClients.Items.Add(c);
260         }
261         /// <summary>
262         /// 删除连接
263         /// </summary>
264         /// <param name="c"></param>
265         private void delItem(string c)
266         {
267             this.lbClients.Items.Remove(c);
268         }
269
270         /// <summary>
271         /// 输出信息
272         /// </summary>
273         /// <param name="msg">信息文本</param>
274         private void setText(string msg)
275         {
276             //不是当前线程调用
277             if (rtbInfo.InvokeRequired)
278             {
279                 MyInvoke _myInvoke = new MyInvoke(setText);
280                 Invoke(_myInvoke, msg);
281             }
282             else
283             {
284                 rtbInfo.AppendText(string.Format("\n{0} {1}", msg, DateTime.Now));
285             }
286         }
287
288         /// <summary>
289         /// 输出错误信息
290         /// </summary>
291         /// <param name="msg">信息文本</param>
292         private void setErrorText(string msg)
293         {
294             //不是当前线程调用
295             if (rtbInfo.InvokeRequired)
296             {
297                 MyInvoke _myInvoke = new MyInvoke(setErrorText);
298                 Invoke(_myInvoke, new object[] { msg });
299             }
300             else
301             {
302                 rtbError.AppendText(string.Format("\n异常:{0} {1}", msg, DateTime.Now));
303             }
304         }
305
306         /// <summary>
307         /// 设置状态栏信息
308         /// </summary>
309         /// <param name="c"></param>
310         private void setState(string c)
311         {
312             //判断是否是创建控件的线程调用
313             if (this.ssState.InvokeRequired)
314             {
315                 MyInvoke invoke = new MyInvoke(setState);
316                 this.Invoke(invoke, new object[] { c });
317             }
318             else
319             {
320                 this.tsslInfo.Text = c;
321             }
322         }
323
324         /// <summary>
325         /// 判断此用户是否存在
326         /// </summary>
327         /// <param name="name"></param>
328         /// <returns></returns>
329         private bool nameIsHave(string name)
330         {
331             for (int i = 0; i < lbClients.Items.Count; i++)
332             {
333                 if (name == lbClients.Items[i].ToString())
334                 {
335                     return true;
336                 }
337             }
338             return false;
339         }
340
341         #endregion
342
343         #region 页面Load事件
344
345         private void ClientForm_Load(object sender, EventArgs e)
346         {
347             btnSendMsg.Enabled = false;
348             txtIp.ReadOnly = true;
349         }
350
351         #endregion
352
353         #region 页面控件事件
354
355         /// <summary>
356         /// 连接服务器
357         /// </summary>
358         /// <param name="sender"></param>
359         /// <param name="e"></param>
360         private void btnLink_Click(object sender, EventArgs e)
361         {
362             if (string.IsNullOrEmpty(txtAccount.Text.Trim()))
363             {
364                 MessageBox.Show("请填写你的聊天用户名!");
365                 return;
366             }
367
368             try { int.Parse(nudPort.Value.ToString()); }
369             catch { MessageBox.Show("端口号错误!"); return; }
370
371             serveraddress = txtIp.Text.Trim();
372             serverport = int.Parse(nudPort.Value.ToString());
373
374             //连接服务器
375             EstablishConnection();
376             //注册
377             RegisterWithServer();
378
379             //连接成功
380             if (connected)
381             {
382                 //接受信息线程
383                 receive = new Thread(new ThreadStart(ReceiveChat));
384                 //启动线程
385                 receive.Start();
386             }
387         }
388
389         /// <summary>
390         /// 发送消息
391         /// </summary>
392         /// <param name="sender"></param>
393         /// <param name="e"></param>
394         private void btnSendMsg_Click(object sender, EventArgs e)
395         {
396             if (string.IsNullOrEmpty(txtMsg.Text.Trim()))
397             {
398                 MessageBox.Show("消息内容不能为空!");
399                 return;
400             }
401             //连接成功
402             if (connected)
403             {
404                 try
405                 {
406                     string command = txtMsg.Text.Trim();
407
408                     //私聊名开始结束位置
409                     int start = command.IndexOf(‘@‘);
410                     int end = command.LastIndexOf(‘@‘);
411                     //私聊名
412                     string rName = (start != -1 && end != -1) ? command.Substring(start + 1, end - 1) : "";
413                     //有@并且名称在系统中 为私聊
414                     if (!string.IsNullOrEmpty(rName) && nameIsHave(rName))
415                     {
416                         //创建私聊
417                         command = string.Format("PRIV|{0}|{1}|{2}", clientname, command.Substring(end + 1, command.Length - end-1), rName);
418                     }
419                     else
420                     {
421                         //创建群发信息
422                         command = string.Format("CHAT|{0}|{1}", clientname, command);
423                     }
424
425                     //转化为字节流
426                     Byte[] outbytes = Encoding.UTF8.GetBytes(command.ToCharArray());
427                     //发送信息
428                     ns.Write(outbytes, 0, outbytes.Length);
429                     txtMsg.Text = "";
430                 }
431                 catch (Exception ex)
432                 {
433                     setErrorText(ex.Message);
434                 }
435             }
436         }
437
438         /// <summary>
439         /// 退出
440         /// </summary>
441         /// <param name="sender"></param>
442         /// <param name="e"></param>
443         private void ClientForm_FormClosed(object sender, FormClosedEventArgs e)
444         {
445             QuitChat();
446         }
447
448         private void rtbInfo_TextChanged(object sender, EventArgs e)
449         {
450             rtbInfo.ScrollToCaret();
451         }
452
453         private void rtbError_TextChanged(object sender, EventArgs e)
454         {
455             rtbError.ScrollToCaret();
456         }
457
458         #endregion

图例

时间: 2024-10-23 13:31:36

Socket聊天室-TcpListener,TcpClient的相关文章

Web Socket 聊天室

Web sockets test Web Socket 聊天室 按下连接按钮,会通过WebSocket发起一个到聊天浏览器的连接. 服务器地址: 用户名: 连接 发送 来自网上.............

python socket 聊天室

import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #绑定端口 s.bind(("127.0.0.1", 8888)) while True: data = s.recvfrom(1024) print(str(data[0].decode("gbk"))) send_data = input("请输入聊天内容") if "exit" in se

【Unity3D自学记录】Unity3D网络之Socket聊天室初探

首先创建一个服务端程序,这个程序就用VS的控制台程序做即可了. 代码例如以下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; namespace SocketServer { class Program { const int Port = 20000; //设置连接port static void Main(strin

【socket】一分钟理清 socket udpsocket tcpsocket tcplistener TCPClient和 UDPClient

socket 套接字接口是各种语言tcp udp的网络操作的基础. 直接用socket 对象开发 可以选择 udpsocket  或者 tcpsocket ,两者在使用上仅一些方法和参数不同,所有的底层都是socket来帮我们实现的 udp重点: { 客户端: Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 服务端: socket.ReceiveFrom    

socket聊天室

1 #服务端 2 from socket import * 3 import json 4 def recvMsg(s): 5 while True: 6 #接收用户的信息 7 data,address = s.recvfrom(1024) 8 data = json.loads(data) 9 print(data,address) 10 11 if data['type'] == 'enter': 12 # 将用户进入聊天室的信息发给其它所有在线用户 13 sendToAll(('>>系统

socket聊天室(服务端)(多线程)(TCP)

#include<string.h> #include<signal.h> #include<stdio.h> #include<sys/socket.h> #include<stdlib.h> #include<netdb.h> #include<pthread.h> #include<memory.h> #include<semaphore.h> int Thread_num=0,count=0

socket 聊天室实现

server #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #includ

socket 聊天室

服务端: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net.Sockets; using System.Net; using System.Thre

PHP+Socket聊天室(telnet命令调试)

class socket { private $_socket; private $_domain = AF_INET; private $_type = SOCK_STREAM; private $_protocol = SOL_TCP; private $_clients = []; private $_max_clients = 10; public function __construct() { if (!extension_loaded('sockets')) { die('the