WebChart网页局域网聊天系列(二):服务器结构及核心代码
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网页局域网聊天系列(二):服务器结构及核心代码的更多相关文章
- WebChart网页局域网聊天系列(一):ActiveX插件编写
第一步:创建ActiveX控件类库,在解决方案中右击添加Window窗体控件库 在该类库属性中,设置 使程序集COM可见,同时设置为COM互操作注册 另外在自动生成的文件中AssemblyInfo.c ...
- C#调用C++系列二:传结构体
这一篇记录下C#调用C++的结构体的方式来使用OpenCV的数据格式,这里会有两种方式,第一种是C#传一个结构体和图像的路径给C++,然后C++将图像加载进来,再把传进来的结构体填满即可,第二种是C# ...
- jvm系列二内存结构
二.内存结构 整体架构 1.程序计数器 作用 用于保存JVM中下一条所要执行的指令的地址 特点 线程私有 CPU会为每个线程分配时间片,当当前线程的时间片使用完以后,CPU就会去执行另一个线程中的代码 ...
- 探究UE4网络系列(二)、UE4网络核心类分析
转载请标明出处:http://www.cnblogs.com/zblade/ 一.概要 前面分析了网络核心的基础类Socket/BSDSocket/SocketSubsystem/SocketSubs ...
- JBoss 系列二十一:JBossCache核心API
内容简介 本处介绍JBossCache相关的主要API,我们目的通过本部分描述,读者可以使用JBossCache API,在自己的应用中使用JBossCache. Cache接口 Cache 接口是和 ...
- 基于EPOLL模型的局域网聊天室和Echo服务器
一.EPOLL的优点 在Linux中,select/poll/epoll是I/O多路复用的三种方式,epoll是Linux系统上独有的高效率I/O多路复用方式,区别于select/poll.先说sel ...
- 机器学习之决策树二-C4.5原理与代码实现
决策树之系列二—C4.5原理与代码实现 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/9435712.html I ...
- [知识库分享系列] 二、.NET(ASP.NET)
最近时间又有了新的想法,当我用新的眼光在整理一些很老的知识库时,发现很多东西都已经过时,或者是很基础很零碎的知识点.如果分享出去大家不看倒好,更担心的是会误人子弟,但为了保证此系列的完整,还是选择分享 ...
- 使用PHP+Swoole实现的网页即时聊天工具:PHPWebIM
使用PHP+Swoole实现的网页即时聊天工具 全异步非阻塞Server,可以同时支持数百万TCP连接在线 同时支持websocket+comet2种兼容协议,可用于所有种类的浏览器包括IE 拥有完整 ...
随机推荐
- 为 Date 对象添加 ago 属性
/* * 此处,__defineGetter__与__defineSetter__相当于C#实体中类中的get与set **/ Date.prototype.__defineGetter__('ago ...
- javascript 第26节 jQuery对象
<html> <head> <title>jQuery</title> <!--导入jquery库--> <script type=& ...
- JSP编程中常用的JavaScript技术(转载)
1.<tronMouseOver=this.style.backgroundColor=’#FFFFFF’ onMouseOut=this.style.backgroundColor=”> ...
- Trie,HDU1875world puzzle
附上代码 #include<iostream> #include<cstdio> #include<string> #include<cstring> ...
- 第46条:for-each循环优先于传统的for循环
for-each循环通过完全隐藏迭代器或者索引变量,避免混乱和出错的可能,适用于集合和数组和任何实现Iterable接口的对象. 使用传统for循环,容易出错: enum Face { ONE, TW ...
- nginx 默认会把header里的参数去掉下划线
做token验证的时候遇到问题:在本地可以获取前端header传的参数,但是部署到服务器获取的就是null(服务器地址用nginx做了代理) 原因: nginx代理默认会把header的参数的 &qu ...
- js 框架都有哪几种(转载)
目前来看,js框架以及一些开发包和库类有如下几个,Dojo .Scriptaculous .Prototype .yui-ext .Jquery .Mochikit.mootools .moo.fxD ...
- 动态获取爱奇艺上传视频mp4格式url地址
有时候,在工作中有些客户需要用到视频,我们大家都知道视频是非常的耗费流量的,因此,如果因为项目要求客户单独买台视频服务器是非常划不来的.那么将视频上传到优酷,爱奇艺等视频网站来托管那是一件很好的解决方 ...
- postal.js使用
requirejs.config({ //默认情况下模块所在目录为js/lib baseUrl: './', //当模块id前缀为app时,他便由js/app加载模块文件 //这里设置的路径是相对与b ...
- switch...case 和 if...else
switch...case与if...else的根本区别在于: switch...case会生成一个跳转表来指示实际的case分支的地址,而这个跳转表的索引号与switch变量的值是相等的,switc ...