
c#多人聊天室
发布日期:2021-05-07 00:06:32
浏览次数:24
分类:精选文章
本文共 7236 字,大约阅读时间需要 24 分钟。
用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(); } ///服务器端:/// 不停接收信息的线程 /// 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 { } } } ////// 发送消息 /// /// /// 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"); } ////// 点第一次连接 第二次关闭连接 /// /// /// 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写完这个小程序有几点需要总结的:alllian = new List (); /// /// 初始化界面 同时开启服务器监听 /// 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 { } } ////// 一直监听 线程只能传object /// /// 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 { } } } ////// 持续接收发来的消息 /// /// 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 { } } } ////// 发送消息给所有人 /// /// /// 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.关于检测对方是否断开连接的方法
百度有不少 心跳包是主流 我的方法是偏方 - -
发表评论
最新留言
不错!
[***.144.177.141]2025年03月27日 04时53分42秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
ACM/NCPC2016 C Card Hand Sorting(upc 3028)
2021-05-08
ubuntu学习笔记-常用文件、命令以及作用(hosts、vim、ssh)
2021-05-08
SLAM学习笔记-求解视觉SLAM问题
2021-05-08
普歌-允异团队-HashMap面试题
2021-05-08
还在一个一个手动安装虚拟机吗?Cobbler自动部署装机一键最小化安装打把游戏就好了
2021-05-08
程序员应该知道的97件事
2021-05-08
create-react-app路由的实现原理
2021-05-08
Linux环境变量配置错误导致命令不能使用(杂谈)
2021-05-08
openstack安装(九)网络服务的安装--控制节点
2021-05-08
shell编程(六)语言编码规范之(变量)
2021-05-08
vimscript学习笔记(二)预备知识
2021-05-08
Android数据库
2021-05-08
HTML基础,块级元素/行内元素/行内块元素辨析【2分钟掌握】
2021-05-08
STM8 GPIO模式
2021-05-08
23种设计模式一:单例模式
2021-05-08
Qt中的析构函数
2021-05-08
C语言实现dijkstra(adjacence matrix)
2021-05-08
三层框架+sql server数据库 实战教学-徐新帅-专题视频课程
2021-05-08
【单片机开发】智能小车工程(经验总结)
2021-05-08