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. JavaScript中关于创建对象的笔记

    1,最基本的两种创建对象的方式:构造函数|| 字面量 构造函数: var person = new Object(); person.name = "chen1zee1"; per ...

  2. Java实战之02Hibernate-08二级缓存

    十四.Hibernate的二级缓存 1.Hibernate的缓存结构 2.由于二级缓存被多线程共享,就必须有一定的事务访问策略 非严格读写:READ UNCOMMITTED 读写型:READ COMM ...

  3. mysql innodb 数据打捞(四)innodb 簇不连续页扫描提取(试验)

    一,用winhex把正常页有意做成不连续的两部分,把后8K向后移动4K,中间隔开4K,启动第一次扫描; 扫描结果是,没有提取到有效页面,但在输出目录生成两个文件:upper.pages和upper.l ...

  4. java.util.AbstractStringBuilder源码分析

    AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大 ...

  5. Java 使用反射拷贝对象一般字段值

    在<Java解惑>上面看到第八十三例--诵读困难者,要求使用非反射实现单例对象的拷贝.查阅了部分资料,先实现通过反射拷贝对象. 1. 编写需要被拷贝的对象Person package co ...

  6. Javascript访问css样式信息

    DOM2级样式为style对象定义了一些属性和方法,可以通过这些方法属性来访问或者修改元素的样式信息: 1.cssText:可读写,在读的情况下以字符串形式返回元素的css代码,在写的情况下以字符串形 ...

  7. jQuery实例-简单选项卡-【一些常见方法(2)-练习】

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 为什么a标签中使用img后的高度多了几个像素?

    a元素下有一个匿名文本,这个文本外有一个匿名行级盒子,它有的默认vertical-align是baseline的,而且往往因为上文line-height的影响,使它有个line-height,从而使其 ...

  9. js中的referrer返回上一页使用介绍

    js中的referrer的用法举例. js完整代码:  <script language="javascript">  var refer=document.refer ...

  10. (用微信扫的静态链接二维码)微信native支付模式官方提供的demo文件中的几个bug修正

    native支付模式一demo(用微信扫的静态链接二维码)BUG修复,一共4个BUG 1.native_call_qrcode.php这个文件中的代码无法生存native支付的短地址2.WxPayPu ...