c#多人聊天室
来源:互联网 发布:科学网 博弈 复杂网络 编辑:程序博客网 时间:2024/06/06 02:46
用c#写的一个多人聊天室的小程序 用的是socket 没用TcpClien以下是代码
客户端:
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;using System.Threading;using System.Net.Sockets;namespace 客户端{ public partial class Form1 : Form { Socket lian; public Form1() { InitializeComponent(); } /// <summary> /// 不停接收信息的线程 /// </summary> void jieshou() { while (true) { Byte[] buff = new Byte[1000]; try { int s = lian.Receive(buff); if (s == 0) break; string str = Encoding.UTF8.GetString(buff, 0, s); this.Invoke(new Action(() => { this.neirong.AppendText(str + "\r\n"); })); } catch { } } } /// <summary> /// 发送消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { if (this.button2.Text != "关闭") { MessageBox.Show("请先连接"); return; } string str = this.liaotian.Text; string strr = this.name.Text + ":" + str; byte[] buf = Encoding.UTF8.GetBytes(strr); try { lian.Send(buf); } catch { //服务器关闭 或者发生异常 断开连接 lian.Close(); MessageBox.Show("请重新连接"); this.button2.Text = "连接"; return; } this.liaotian.Clear(); this.neirong.AppendText("我:" + str + "\r\n"); } /// <summary> /// 点第一次连接 第二次关闭连接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { if (this.button2.Text == "关闭") { lian.Close(); this.button2.Text = "连接"; return; } try { //创建负责通信的Socket lian = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ip = IPAddress.Parse("127.0.0.1"); IPEndPoint point = new IPEndPoint(ip, 3333); //获得要连接的远程服务器应用程序的IP地址和端口号 lian.Connect(point); //开启一个新的线程不停的接收服务端发来的消息 Thread t = new Thread(jieshou); t.IsBackground = true; t.Start(); this.button2.Text = "关闭"; } catch { } } }}服务器端:
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.Threading;namespace 聊天室{ public partial class Form1 : Form { //所有通信的socket List<Socket> alllian = new List<Socket>(); /// <summary> /// 初始化界面 同时开启服务器监听 /// </summary> public Form1() { InitializeComponent(); //防止线程无法访问ui界面的控件 但是隐患太大 推荐使用this.Invoke(new Action(() => //Control.CheckForIllegalCrossThreadCalls = false; try { //新建套接字 Socket jianting = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 绑定 可用ip jianting.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3333)); //同时连接的最大上限 多了排队 jianting.Listen(2); //创建后台线程一直等待连接连接 Thread t = new Thread(lianjie); t.IsBackground = true; t.Start(jianting); } catch { } } /// <summary> /// 一直监听 线程只能传object /// </summary> /// <param name="jianting"></param> void lianjie(object jianting) { while (true) { Socket jt = (Socket)jianting; //返回通信的套接字 try { Socket l = jt.Accept(); //持续接收消息 alllian.Add(l); Thread t = new Thread(jieshou); t.IsBackground = true; t.Start(l); } catch { } } } /// <summary> /// 持续接收发来的消息 /// </summary> /// <param name="l"></param> void jieshou(object ll) { Socket l = (Socket)ll; while (true) { Byte[] buff = new Byte[1000]; try { int s = l.Receive(buff); if (s == 0) { alllian.Remove(l); break; } //显示内容 string str = Encoding.UTF8.GetString(buff, 0, s); this.Invoke(new Action(() => { this.neirong.AppendText(str + "\r\n"); })); buff = Encoding.UTF8.GetBytes(str); //发送给别人 直接用发来bytes转发的话有一些问题 长度不匹配 foreach (Socket all in alllian) { if (all != l) try { all.Send(buff); } catch { continue; } } } catch { } } } /// <summary> /// 发送消息给所有人 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void fasong_Click(object sender, EventArgs e) { bool r=false; string str = this.liaotian.Text; string strr = "房主:" + str; byte[] buf = Encoding.UTF8.GetBytes(strr); //给所有人发送消息 不要用foreach 报错 集合已修改 无法进行枚举操作 for (int i = 0; i < alllian.Count;i++ ) { try { alllian[i].Send(buf); r = true; } catch { alllian.Remove(alllian[i]); i--; continue; } } //如果可以发送出去消息 则还有人连接 if (r) { this.liaotian.Clear(); this.neirong.AppendText("我:"+str + "\r\n"); } else { alllian.Clear(); MessageBox.Show("无人聊天"); } } }}写完这个小程序有几点需要总结的:
1.socket、线程、集合的使用
socket:多练练就会用了 网上资料不少
线程:传参数只能是object 之后可强转 可 as(比较安全) winform程序线程想访问控件最好使用
this.Invoke(new Action(() => 这类的操作
而 Control.CheckForIllegalCrossThreadCalls = false; 只是拆了东墙补
集合:在循环里进行操作勿用foreach 比如集合在删除中间元素的时候后面的元素会往前移动 for删除完元素之后 i--退一位即可
2.通信的双方不能明确的知晓对方是否断开连接
服务器:客户端断开连接,服务器发送消息的时候会报异常
客户端:服务器关闭 ,客户端发送消息会报异常
捕捉这个异常 则证明对方断开连接 做相应的处理(这样不太正规,万一不是断开连接引起的异常就不好了) 这个我用着还可以
3.关于检测对方是否断开连接的方法
百度有不少 心跳包是主流 我的方法是偏方 - -
阅读全文
1 0
- c#多人聊天室
- 多人聊天室程序(P2P)C#版
- C#聊天室
- 简易多人聊天室
- 多人聊天室
- 多人聊天室
- C# 局域网聊天室
- C# Socket 异步 聊天室
- C# WebSocket 聊天室
- c#网络点对点聊天室
- c# MongoDB 聊天室搭建
- C#简单聊天室雏形
- python socket 多人聊天室
- 【linux】多人聊天室实现
- python socket多人聊天室
- nodejs +webSocket 多人聊天室
- Unity简单多人聊天室
- Java编写多人聊天室
- 自定义ImageView点击实现两张图片切换
- 圣杯布局【双飞翼布局】的几种实现
- GIT知识杂记
- Android WebView控件使用介绍
- 建筑工程师的转行学计算机科学与技术的抉择
- c#多人聊天室
- 使用echarts实现动态显示折线图
- NOIP2013华容道 大爆搜
- Android N DisplayManager服务解析(二)
- 【HDU1068】Girls and Boys(最大独立集数,匈牙利算法)
- ActiveMQ整合Spring
- 虚树学习小结
- windows安装sbt以及eclipse 安装scala插件
- strongloop loopback 禁用指定API