public partial class MainForm : Form
{
private Socket server;//服务器Socket
private int userNum;//当前在线用户数
private int socketNum;//当前socket数
private Socket[] userSocket = new Socket[40];//存储用户socket public MainForm()
{
InitializeComponent(); Thread startThread = new Thread(new ThreadStart(Listen));
startThread.Start();
} /// <summary>
/// 监听
/// </summary>
private void Listen()
{
userNum = 0;
socketNum = 0; IPEndPoint iep = new IPEndPoint(IPAddress.Parse(ConfigurationManager.AppSettings["serverIp"]), int.Parse(ConfigurationManager.AppSettings["serverPort"]));
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
server.Bind(iep);
server.Listen(20);
richMsg.AppendText(string.Format("服务器已启动,等待WEB客户端连接\r\n"));
}
catch (Exception ex)
{
richMsg.AppendText(string.Format("服务器启动失败,错误原因:{0}\r\n", ex.Message));
}
AcceptUser();
} /// <summary>
/// 接受用户连接
/// </summary>
private void AcceptUser()
{
while (true)
{
try
{
Socket nowClient = server.Accept();
userSocket[socketNum++] = nowClient;
userNum++;
richMsg.AppendText(string.Format("有新的用户接入,当前在线用户数:{0}\r\n", userNum)); Thread nowThread = new Thread(new ParameterizedThreadStart(ReciveData));
nowThread.Start(nowClient);
}
catch (Exception ex)
{
richMsg.AppendText(string.Format("新用户接入失败:错误原因:{0}\r\n", ex.Message));
}
}
} /// <summary>
/// 接收客户端发过来的消息
/// </summary>
/// <param name="client"></param>
private void ReciveData(object client)
{
Socket nowClient = (Socket)client;
while (true)
{
int res = 0;
byte[] bytes = new byte[1024];
try
{
res = nowClient.Receive(bytes);
string str = Encoding.UTF8.GetString(bytes, 0, res);
richMsg.AppendText(string.Format("{0}\r\n", str)); byte[] data = Encoding.UTF8.GetBytes(str);
SendAllUser(data, nowClient);
}
catch (Exception ex)
{
richMsg.AppendText(string.Format("接收用户消息失败:错误原因:{0}\r\n", ex.Message));
}
}
} /// <summary>
/// 转发给其他所有用户
/// </summary>
/// <param name="data"></param>
/// <param name="nowClient"></param>
private void SendAllUser(byte[] data,Socket nowClient)
{
if (userNum > 0)
{
for (int i = 0; i < socketNum; i++)
{
if (userSocket[i].Equals(nowClient))
continue;
try
{
userSocket[i].Send(data);
richMsg.AppendText(string.Format("消息转发成功!\r\n"));
}
catch (Exception ex)
{
userSocket[i] = userSocket[socketNum - 1];
socketNum--;
i--;
richMsg.AppendText(string.Format("用户断线,当前在线用户数:{0},断线原因:{1}\r\n", socketNum, ex.Message));
}
}
}
}
}

WebChart网页局域网聊天系列(二):服务器结构及核心代码的更多相关文章

  1. WebChart网页局域网聊天系列(一):ActiveX插件编写

    第一步:创建ActiveX控件类库,在解决方案中右击添加Window窗体控件库 在该类库属性中,设置 使程序集COM可见,同时设置为COM互操作注册 另外在自动生成的文件中AssemblyInfo.c ...

  2. C#调用C++系列二:传结构体

    这一篇记录下C#调用C++的结构体的方式来使用OpenCV的数据格式,这里会有两种方式,第一种是C#传一个结构体和图像的路径给C++,然后C++将图像加载进来,再把传进来的结构体填满即可,第二种是C# ...

  3. jvm系列二内存结构

    二.内存结构 整体架构 1.程序计数器 作用 用于保存JVM中下一条所要执行的指令的地址 特点 线程私有 CPU会为每个线程分配时间片,当当前线程的时间片使用完以后,CPU就会去执行另一个线程中的代码 ...

  4. 探究UE4网络系列(二)、UE4网络核心类分析

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.概要 前面分析了网络核心的基础类Socket/BSDSocket/SocketSubsystem/SocketSubs ...

  5. JBoss 系列二十一:JBossCache核心API

    内容简介 本处介绍JBossCache相关的主要API,我们目的通过本部分描述,读者可以使用JBossCache API,在自己的应用中使用JBossCache. Cache接口 Cache 接口是和 ...

  6. 基于EPOLL模型的局域网聊天室和Echo服务器

    一.EPOLL的优点 在Linux中,select/poll/epoll是I/O多路复用的三种方式,epoll是Linux系统上独有的高效率I/O多路复用方式,区别于select/poll.先说sel ...

  7. 机器学习之决策树二-C4.5原理与代码实现

    决策树之系列二—C4.5原理与代码实现 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/9435712.html I ...

  8. [知识库分享系列] 二、.NET(ASP.NET)

    最近时间又有了新的想法,当我用新的眼光在整理一些很老的知识库时,发现很多东西都已经过时,或者是很基础很零碎的知识点.如果分享出去大家不看倒好,更担心的是会误人子弟,但为了保证此系列的完整,还是选择分享 ...

  9. 使用PHP+Swoole实现的网页即时聊天工具:PHPWebIM

    使用PHP+Swoole实现的网页即时聊天工具 全异步非阻塞Server,可以同时支持数百万TCP连接在线 同时支持websocket+comet2种兼容协议,可用于所有种类的浏览器包括IE 拥有完整 ...

随机推荐

  1. 10_控制线程_线程让步yield

    [线程让步yield()方法] yield()方法可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程从运行状态转入就绪状态. 只是让当前的线程暂停一下,让系统的线程调度器重新调度一次. ...

  2. C++输入结束

    通过判断输入是否等于EOF,可以结束输入. EOF 是个宏,其意思是:End Of File,文件尾标志. 从数值上来看,就是整数-1. 在C语言的头文件中对其进行了宏定义: libio.h:     ...

  3. VC++ CTime Format 详解

    参考链接: VC++中CTime类Format参数详解 CTime/COleDateTime::Format方法的使用 http://stat.ethz.ch/R-manual/R-devel/lib ...

  4. table隔行换色

    以前做表格隔行换色,是在tr上添加不同的背景色,但在程序开发的过程需要做判断,不够方便,而且生成的代码也比较多,现在的需求逐渐修改为JQ去控制简洁的表格去显示隔行换色 <script type= ...

  5. 三种读写XML的方法

    XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影.Xml是Internet环境中跨平台的,依赖于内 ...

  6. java根据url获取json对象

    package test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; ...

  7. PHPCMS如何实现后台访问限制?

    修改phpcms 后台管理路径,可以有效的防止因为程序漏洞,或者是服务器安全问题所带来的 phpcms系统管理权限被黑客获取 文件路径:/caches/config/system.php 修改:'ad ...

  8. 【python】迭代一列 斐波那契数列

    def fabm(n): if n < 1: print('输入不能小于1') return -1 if n == 1 or n == 2: return 1 else: return fabm ...

  9. oracle LogMiner配置使用

    一.安装LogMiner1.@D:\app\product\11.1.0\db_1\RDBMS\ADMIN\dbmslm.sql 2.@D:\app\product\11.1.0\db_1\RDBMS ...

  10. Html5 布局经验分享-第1集

    移动端的布局与pc端的布局相比 移动端的布局就简单的多,兼容性不必考虑那么多,css3各种特性基本上是可以放肆的写:(个人看法) 本人做移动web 布局一段时间了,把这其中遇到的一些问题总结下来,均是 ...