数往知来 asp.net 聊天室问题解决方案<十六>

 

1:在服务端创建了一个负责监听的sokcet

  //三个:采用TCP协议.

             ListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPAddress ipAddress = IPAddress.Parse(this.txtIP.Text);//获取IP地址.

            IPEndPoint point = new IPEndPoint(ipAddress, Convert.ToInt32(this.txtPort.Text));

//通信节点.包含了IP地址与端口号.

            ListenSocket.Bind(point);//将通信节点(IP地址与端口号)与负责监听的Socket进行绑定。

        ListenSocket.Listen(10);//设置监听队列.(将当前的Socket设置侦听状态)

2:解决服务端Accept方法占用UI线程的问题.(必做)

ThreadStart start = new ThreadStart(AcceptConnection);

            Thread thread = new Thread(start);

            thread.IsBackground = true;

//设置后台线程.如果整个的服务端窗体关闭,也就没有必要再等带客户端了,

所以在这里把该线程设置为后台线程。

            thread.Start();

3:解决多个客户端请求,针对不同的客户端创建单独的newSocket(可选)

  public void AcceptConnection()

        {

            while (true)//由于每个客户端必须都有一个单独的newSocket实例与之进行交流,

所以我们服务端得Accept()方法一致等待客户端有没有链接过来。

            {

                Socket newSocket = ListenSocket.Accept();

//获取到一个客户端的请求,创建一个新的Socket,负责与客户端进行交流

。每个客户都要创建一个单独的newSocket.

                ShowMsg("客户端链接成功");

            }

        }

4:客户端怎样连接了服务端.

在客户端中添加如下代码:

   Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPAddress ipAddress = IPAddress.Parse(this.txtIP.Text);//获取IP地址.

            IPEndPoint endPoint = new IPEndPoint(ipAddress,Convert.ToInt32(this.txtPort.Text));

            //clientSocket.Bind(endPoint);

            clientSocket.Connect(endPoint);//客户端根据通信节点去链接服务端。在客户端不能进行Bind操作.

5:服务端怎样向客户端发送文本数据.

首先在服务添加如下代码

/// <summary>

        /// 服务端向客户端发送文本数据(发送按钮)

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnSendMsg_Click(object sender, EventArgs e)

        {

            string sendMsg = this.txtSendMsg.Text;

            byte[] buffer=System.Text.Encoding.UTF8.GetBytes(sendMsg);//send发送的是字节数组.

            newSocket.Send(buffer);//服务端向客户端发送数据.

            ShowMsg("发送成功!");

        }

以上代码中我们将newSocket定义了一个全局变量,这样会有问题。

客户端的代码(放在了客户端的 private void btnStartListen_Click(object sender, EventArgs e)方法中)

            byte[] buffer=new byte[1024*1024*2];

            clientSocket.Receive(buffer);

//接收服务端发过来的数据,该法会让客户端的Socket一直处于一种接收状态。

所以该方法也会占用UI线程。

            string receiveMsg=System.Text.Encoding.UTF8.GetString(buffer);

            ShowMsg(receiveMsg);

6:解决客户端接收数据的Receive方法占用UI线程问题,以及newSocket全局问题

客户端解决Receive占用UI线程问题。

            ThreadStart start = new ThreadStart(ReciveClient);

//解决客户端接收Receive方法占用UI线程的问题。

            Thread thread = new Thread(start);

            thread.IsBackground = true;

            thread.Start();

  public void ReciveClient()

        {

            byte[] buffer = new byte[1024 * 1024 * 2];

            clientSocket.Receive(buffer);

//接收服务端发过来的数据,该法会让客户端的Socket一直处于一种接收状态。

所以该方法也会占用UI线程。

            string receiveMsg = System.Text.Encoding.UTF8.GetString(buffer);

            ShowMsg(receiveMsg);

        }

7:解决newSocket全局问题

//将与客户端进行数据交流的newSocket放入该集合中。

        Dictionary<string, Socket> dictSocket = new Dictionary<string, Socket>();

        public void AcceptConnection()

        {

            while (true)//由于每个客户端必须都有一个单独的newSocket实例与之进行交流,

所以我们服务端得Accept()方法一致等待客户端有没有链接过来。

            {

              Socket   newSocket = ListenSocket.Accept();//获取到一个客户端的请求,

创建一个新的Socket,负责与客户端进行交流。每个客户都要创建一个单独的newSocket.

              //将每个与客户端进行交流的newSocket添加到集合中,

我们用远程的客户端的IP地址与端口号作为集合的key.

              dictSocket.Add(newSocket.RemoteEndPoint.ToString(), newSocket);

                //将客户端的IP地址与端口号放在了列表中

              this.listOnline.Items.Add(newSocket.RemoteEndPoint.ToString());

                ShowMsg("客户端链接成功");

            }

        }

  /// <summary>

        /// 服务端向客户端发送文本数据

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btnSendMsg_Click(object sender, EventArgs e)

        {

            string sendMsg = this.txtSendMsg.Text;

            byte[] buffer=System.Text.Encoding.UTF8.GetBytes(sendMsg);//send发送的是字节数组.

            string clientIp = this.listOnline.Text;

            if (!string.IsNullOrEmpty(clientIp))

            {

                //newSocket.Send(buffer);//服务端向客户端发送数据.

                //根据用户在listBox列表中选择的客户端的iP地址与端口号,找到该客户端对应的newSocket.

                dictSocket[clientIp].Send(buffer);

                ShowMsg("发送成功!");

            }

            else

            {

                MessageBox.Show("请选择要发送的客户端");

            }

        }

8:客户端一直处于接收状态.

while (true)//也要让客户端一直处于接收状态.(只是增加了改循环)

            {

                byte[] buffer = new byte[1024 * 1024 * 2];

                clientSocket.Receive(buffer);

//接收服务端发过来的数据,该法会让客户端的Socket一直处于一种接收状态。

所以该方法也会占用UI线程。

                string receiveMsg = System.Text.Encoding.UTF8.GetString(buffer);

                ShowMsg(receiveMsg);

            }

9:解决回车换行问题.

public void ReciveClient()

        {

            while (true)//也要让客户端一直处于接收状态.

            {

                byte[] buffer = new byte[1024 * 1024 * 2];

                int receiveLength=clientSocket.Receive(buffer);

//接收服务端发过来的数据,该法会让客户端的Socket一直处于一种接收状态

。所以该方法也会占用UI线程。

                //如果接收的服务端发过来的数据不足2M,那么剩余的存储单元都用"\0"来填充,

而"\0"表示字符串的结束,所以我们在接受的字符串后面加回车换行时无效。

              // string receiveMsg = System.Text.Encoding.UTF8.GetString(buffer);

                //sokecet中的Receive方法会将接收到的数据填充到字节数组中,同时返回一个整数,

表示实际接收的数据长度。那么我们在将字节数组转成字符串时,从字节数组中的第一位开始,

一直实际接收的数据长度接收。这时不包含\0,

                string receiveMsg = System.Text.Encoding.UTF8.GetString(buffer, 0, receiveLength);

                ShowMsg(receiveMsg);

            }

}
时间: 2024-12-11 15:24:20

数往知来 asp.net 聊天室问题解决方案<十六>的相关文章

数往知来 ASP.NET Cookie Session Url &lt;二十九&gt;

ViewState_Cookie 一.Request的几个成员 -->Request.UrlReferrer():请求的来源,就是客户端上一次请求的url地址,防止盗链 -->Request.UrlHostAddress;获取浏览器端的IP地址,通过Socket.RemoveEndPoint  获得的客户端IP地址 -->Request.MapPath();   跟context.ServerMapPath()一样 二.Response的成员 -->Respose.Buffer 缓

ASP.NET Core 2.2 : 二十六. 应用JWT进行用户认证及Token的刷新

来源:https://www.cnblogs.com/FlyLolo/p/ASPNETCore2_26.html 本文将通过实际的例子来演示如何在ASP.NET Core中应用JWT进行用户认证以及Token的刷新方案(ASP.NET Core 系列目录) 一.什么是JWT? JWT(json web token)基于开放标准(RFC 7519),是一种无状态的分布式的身份验证方式,主要用于在网络应用环境间安全地传递声明.它是基于JSON的,所以它也像json一样可以在.Net.JAVA.Jav

SilverLight搭建WCF聊天室详细过程[转]

http://www.silverlightchina.net/html/zhuantixilie/getstart/2011/0424/7148.html 默认节点 SilverLight搭建WCF聊天室详细过程(二十一)关于聊天室项目错误 SilverLight搭建WCF聊天室详细过程(二十)WCF服务端用户列表字 SilverLight搭建WCF聊天室详细过程(五)好友下线 SilverLight搭建WCF聊天室详细过程(九)接收文本消息 SilverLight搭建WCF聊天室详细过程(三

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十四)之漏掉的客服消息

前言 不知不觉已经十四篇了,其实已经没有什么可写了.但是突然发现layim中带的客服功能没有用到.于是乎,抽点时间完成吧.其实之前的工作已经把客服功能完成了一大半,剩下的我们稍微调整即可.今天的演示我们放在后边,直接进入讲解. 客服思路讲解 大家去一些公司网站都会发现,网页侧面或者自动弹出一些客服聊天框,人家很热情的和你交谈.我们也可以用layim来实现.首先,页面添加一个按钮,点击按钮触发客服模式. <a onclick="javascript:global.other.kefu(148

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十) 之 自定义系统消息和总结

前言 本篇是<ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室>系列博客最后一篇,因为该介绍的都已经介绍了,基本原理也都是一样的.不过GitHub代码还是会更新,本篇就是结束篇了.在写博过程中,好多网友给了我支持和意见.非常感谢各位大牛对本学习项目的关注和支持.当然最重要的还要感谢LayIM团队能够出这么优秀的产品. 本篇主要讲解一个东西,就是我们自定义系统消息.效果如下: 首先我们要做的准备工作就是改写 layim 的消息模板,如果不改的话就成为某个用户发送的消

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(四) 之 用户搜索(Elasticsearch),加好友流程(1)。

前面几篇基本已经实现了大部分即时通讯功能:聊天,群聊,发送文件,图片,消息.不过这些业务都是比较粗犷的.下面我们就把业务细化,之前用的是死数据,那我们就从加好友开始吧.加好友,首先你得知道你要加谁.Layim界面右下角有个+号,点击它之后就会弹出查找好友的界面,不过那个界面需要自定义.由于前端不是我的强项,勉强凑了个页面.不过不要在意这些细节.这些都不重要,今天主要介绍一下ElasticSearch搜索解决方案.它是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(七) 之 历史记录查询(时间,关键字,图片,文件),关键字高亮显示。

前言 上一篇讲解了如何自定义右键菜单,都是前端的内容,本篇内容就一个:查询.聊天历史纪录查询,在之前介绍查找好友的那篇博客里已经提到过 Elasticsearch,今天它又要上场了.对于Elasticsearch不感冒的同学呢,本篇可以不用看啦. from baidu: ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)

大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言  ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM界面中的数据动态化.当然还不涉及即时消息通讯,如果你已经搞定了数据界面,那么本文您可以简单的看一下,或者略过. 进入正题,layim帮我们定义好了数据规则,我们只要写一个接口实现那个json规范就可以了,剩下的事情就交给layim去做,看一下json格式.(对应文件夹:demo/json/getLi

ASP.NET 使用application和session对象写的简单聊天室程序

ASP.Net中有两个重要的对象,一个是application对象,一个是session对象. Application:记录应用程序参数的对象,该对象用于共享应用程序级信息. Session:记录浏览器端的变量对象,用来存储跨网页程序程序的变量或者对象. 说实话,写了快一年的asp.net,application对象还真没怎么用过.看了看书,根据这两个对象的特性写了一个简单的聊天室程序.真的是非常的简陋. 我的思路是,有两个页面Default页和ChatRoom页,页面布局如图: Default