Socket入门笔记 用TcpClient实现一个简易聊天室
效果

实现思路
使用TcpListener建一个服务器,接收所有客户端发送的消息,然后由服务器再发送到其他客户端
客户端使用TcpClient,发消息给服务器,接收服务器的消息,不和其他客户端直接交互
服务器端
接收客户端
开启一个线程,死循环去接收客户端.接收到之后放到一个集合里,保存起来,以便转发消息用.每个客户端都再开启一个线程,用于接收这个客户端发送的消息.
接收客户端的方法AcceptTcpClient()是阻塞方法,在程序退出释放资源时会引发异常,可以先使用Pending()方法先判断是否有挂起的链接请求,有请求的话再去接收.这样可以避免退出时引发的异常.
这里取每隔1秒接收一次.
/// <summary>
/// 接收客户端
/// </summary>
private void AcceptClient()
{
try
{
while (_isAccept)
{
if (_listener.Pending())
{
TcpClient client = _listener.AcceptTcpClient();
IPEndPoint endpoint = client.Client.RemoteEndPoint as IPEndPoint;
_clients.Add(endpoint.ToString(), client);
//添加到前端客户端列表
lbx_Clients.Dispatcher.Invoke(() =>
{
lbx_Clients.Items.Add(endpoint.ToString());
});
//接收消息线程
Thread reciveMessageThread = new Thread(ReciveMessage);
reciveMessageThread.Start(client);
}
else
{
Thread.Sleep();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
接收消息并转发
也是死循环接收,使用Read()方法接收.如果远程主机已关闭连接,Read()将立即返回零字节.此时跳出循环,释放资源,结束此线程.
/// <summary>
/// 接收消息
/// </summary>
/// <param name="obj">TcpClient</param>
private void ReciveMessage(object obj)
{
TcpClient client = obj as TcpClient;
IPEndPoint endpoint = null;
NetworkStream stream = null;
try
{
endpoint = client.Client.RemoteEndPoint as IPEndPoint;
stream = client.GetStream();
while (true)
{
];
//如果远程主机已关闭连接,Read将立即返回零字节
, data.Length);
)
{
#region if
, length);
//添加到前端消息列表
lbx_Messages.Dispatcher.Invoke(() =>
{
lbx_Messages.Items.Add(string.Format("{0}:{1}", endpoint.ToString(), msg));
});
//发送到其他客户端
foreach (KeyValuePair<string, TcpClient> kvp in _clients)
{
if (kvp.Value != client)
{
string writeMsg = string.Format("{0}:{1}", endpoint.ToString(), msg);
byte[] writeData = Encoding.UTF8.GetBytes(writeMsg);
NetworkStream writeStream = kvp.Value.GetStream();
writeStream.Write(writeData, , writeData.Length);
}
}
#endregion
}
else
{
//客户端断开连接 跳出循环
break;
}
}
}
catch (Exception ex)
{
//Read是阻塞方法 客户端退出是会引发异常 释放资源 结束此线程
}
finally
{
//从前端客户端列表移除
lbx_Clients.Dispatcher.Invoke(() =>
{
lbx_Clients.Items.Remove(endpoint.ToString());
});
//释放资源
stream.Dispose();
_clients.Remove(endpoint.ToString());
client.Dispose();
}
}
客户端
接收消息
开启线程,死循环接收服务器发送的消息.如果Read()返回0,说明服务器已关闭.
/// <summary>
/// 接收消息
/// </summary>
private void ReciveMessage()
{
try
{
NetworkStream stream = _client.GetStream();
while (true)
{
];
, data.Length);
)
{
, length);
//添加到前端消息列表
lbx_Messages.Dispatcher.Invoke(() =>
{
lbx_Messages.Items.Add(msg);
});
}
else
{
MessageBox.Show("服务器已关闭");
stream.Dispose();
break;
}
}
}
catch (Exception ex)
{
//Read是阻塞方法 程序退出释放资源是会引发异常 不做处理 线程结束
}
}
源码下载:
服务器端:SocketServerDemo.zip
Socket入门笔记 用TcpClient实现一个简易聊天室的更多相关文章
- Python开发【笔记】:aiohttp搭建简易聊天室
简易聊天室: 1.入口main.py import logging import jinja2 import aiohttp_jinja2 from aiohttp import web from a ...
- vue + socket.io实现一个简易聊天室
vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度.因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那 ...
- 真刀实战地搭建React+Webpack+Express搭建一个简易聊天室
一.前面bb两句 因为自惭(自残)webpack配置还不够熟悉,想折腾着做一个小实例熟悉.想着七夕快到了,做一个聊天室自己和自己聊天吧哈哈.好了,可以停止bb了,说一下干货. 二. 这个项目能学到啥? ...
- 原生NodeJs制作一个简易聊天室
准备工作 安装NodeJs环境 安装编译器Sublime 如果网速不理想,可以百度一下如何加快npm的速度~ 使用node搭建一个简单的网站后台 做完准备工作之后,新建文件夹chatroom,在cha ...
- Socket实现简易聊天室,Client,Server
package seday08; import java.io.BufferedWriter;import java.io.OutputStream;import java.io.OutputStre ...
- node+websocket创建简易聊天室
关于websocket的介绍太多,在这就不一一介绍了,本文主要实现通过websocket创建一个简易聊天室,就是90年代那种聊天室 服务端 1.安装ws模块,uuid模块,ws是websocket模块 ...
- node.js+websocket实现简易聊天室
(文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) websocket提供了一种全双工客户端服务器的异步通信方法,这种通信方法使用ws或者wss协议,可 ...
- php_D3_“简易聊天室 ”实现的关键技术 详解
PHP+MySQL实现Internet上一个简易聊天室的关键技术 系统目标: 聊天室使用数据库汇集每个人的发言,并可将数据库内的发言信息显示在页面,让每个用户都可 ...
- 示例:Socket应用之简易聊天室
在实际应用中,Server总是在指定的端口上监听是否有Client请求,一旦监听到Client请求,Server就会启动一个线程来响应该请求,而Server本身在启动完线程之后马上又进入监听状态. 示 ...
随机推荐
- 移动端web页面开发常用的头部标签设置
在移动端web页面开发中,我们常需要设置各种头部标签以帮助浏览器更好的解析页面,将页面完美呈现,这里列出了工作中常用的各种头部标签,以备查询. viewport <meta name=" ...
- linux 下的ssh
ssh服务 1.检查是否有被安装,命令 rpm -qa|grep "ssh" 2.检查ssh有没有在运行,命令 rpm -qa|grep "ssh" 3.如何启 ...
- 基于 node 搭建博客系统(一)
系统分为两端,分别实现. 管理员端: 功能 :个人信息,设置,发布随笔,随笔列表,删除随笔,查找,文章 等. 技术点:Boostrap + AdminLTE; 基于nodejs 实现的express ...
- 洗礼灵魂,修炼python(31)--面向对象编程(1)—面向对象,对象,类的了解
面向对象 1.什么是面向对象 (图片来自网络) 哈哈,当然不是图中的意思. 1).面向对象(Object Oriented,OO)是软件开发方法.利用各大搜索引擎得到的解释都太官方,完全看不懂啥意思对 ...
- SQL Server 临时表和表变量系列之选择篇
原文地址:https://yq.aliyun.com/articles/69187 摘要: # 摘要 通过前面的三篇系列文章,我们对临时表和表变量的概念.对比和认知误区已经有了非常全面的认识.其实,我 ...
- scrapy爬取校花网男神图片保存到本地
爬虫四部曲,本人按自己的步骤来写,可能有很多漏洞,望各位大神指点指点 1.创建项目 scrapy startproject xiaohuawang scrapy.cfg: 项目的配置文件xiaohua ...
- STL set简单用法
set的常见用法详解 set翻译为集合,是一个内部自动有序并且不含重复元素的容器. 可以用于去掉重复元素,或者元素过大,或者不能散列的情况,set只保留元素本身而不考虑它的个数. 头文件:#inclu ...
- Instruments模板介绍(更新中...)
第一章.Instruments(仪器)快速入门 Instruments可以用来收集关于一个或者多个系统进程的性能和行为的数据,并跟踪睡着时间产生的数据.它提供了好几个分析模板: Blank 任何类型都 ...
- svn 更新
dev更新流程: 1.打开软件,文件—>打开,弹出右边对话框链接dev地址 2.在窗口输入cd /var/www/user 回车 3.输入svn up 则更新dev代码完成 本地提交到 ...
- 网络编程_UDP协议_发送端与接收端
创建UDP传输的发送端 : 1.建立udp的socket服务 2.将要发送的数据封装到数据包中 3.通过udp的socket服务 将数据包发送出去 4.关闭socket服务(因为调用了系统 ...