0.基于上一篇的c#之Socket(同步)通信,在几个大神评论之后,发现是有挺多地方不足的,所以写了一个改进版本的基于c#的异步Socket通信。再加深一下对Socket的使用和理解。其中客户端和服务端均采用WPF界面,实现了心跳,断线重连,一个服务端对应多个客户端的功能。

一.服务端

1.1 先创建一个Socket实例,并绑定到20000端口号;通过Listen方法开始监听并设置最大监听数量。

//新建一个Socket服务端实例,并绑定到20000端口
this.socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.socketServer.Bind(new IPEndPoint(IPAddress.Any, )); //设置最大监听数量
this.socketServer.Listen();

1.2 开始异步监听客户端,使用的是BeginAccept与EndAccept,当有客户端连接后会自动调用回调函数,此时开始心跳并将客户端的Socket与心跳等信息加入到全局字典中去。

this.socketServer.BeginAccept(ar =>
{
Socket _socket = socketServer.EndAccept(ar); //开始心跳
System.Timers.Timer heartbeatTimer = new System.Timers.Timer();
heartbeatTimer.Interval = ;
heartbeatTimer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => heartbeatTimerIsUp(s, e, _socket));
heartbeatTimer.Start(); SocketInfo info = new SocketInfo();
info.heartbeatTimer = heartbeatTimer;
this.socketInfoDic.Add(_socket, info); //开始接收数据
thdRevMethod(_socket);
//开始下一次监听
ListenSocket();
}, null);

1.3 接收数据,当上一步中有客户端连接成功后,即可开启异步接收来自客户端的数据;使用的是BeginReceive与EndReceive,当接收到来自客户端的数据后,会自动调用回调函数。由于接收到的数据的大小不确定,所以这里每次接收1024字节,然后将接收到的数据拼接起来,用到Available 属性,为可读取的字节数,如果小于等于0,说明此次数据接收完毕。

Socket _socket = obj as Socket;
if (this.socketInfoDic.ContainsKey(_socket))
{
SocketInfo socketInfo = socketInfoDic[_socket];
//开始接收消息
_socket.BeginReceive(socketInfo.tempByte, , socketInfo.tempByte.Length, SocketFlags.None, ar =>
{
try
{
int resInt = _socket.EndReceive(ar);
socketInfo.contentByte = socketInfo.contentByte.Concat(socketInfo.tempByte).ToArray();
socketInfo.tempByte = new byte[];
if (_socket.Available <= )
{
int actualLength = socketInfo.contentByte.Length - (socketInfo.tempByte.Length - resInt);
string res = Encoding.Default.GetString(socketInfo.contentByte, , actualLength);
socketInfo.contentByte = new byte[];
}
thdRevMethod(_socket);
}
catch (SocketException sex)
{
if (sex.SocketErrorCode == SocketError.ConnectionReset)
{
//当客户端断开连接,从列表中移除该客户端
if (this.socketInfoDic.ContainsKey(_socket))
{
this.socketInfoDic.Remove(_socket);
}
}
}
catch (Exception ex)
{
MessageBox.Show("程序出现异常:" + ex);
}
}, null);
}

1.4 发送数据,用到的是BeginSend与EndSend,发送成功后会自动调用回调函数,其中EndSend()方法返回成功发送的字节数量

byte[] byteStr = Encoding.Default.GetBytes(msg);
_socket.BeginSend(byteStr, , byteStr.Length, SocketFlags.None, ar =>
{
_socket.EndSend(ar);
}, null);

二.客户端

2.1 新建Socket实例并开始异步连接到服务端,用到的是BeginConnect与EndConnect,连接成功会自动调用回调函数,此时可开始心跳,接收发送数据。

// 新建客户端实例,并连接到服务端所在的端口号
this.socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //连接到服务端
this.socketClient.BeginConnect("127.0.0.1", , ar =>
{
try
{
this.socketClient.EndConnect(ar);
this.thdRevMethod();
}
catch (SocketException sex)
{
if (sex.SocketErrorCode == SocketError.ConnectionRefused)
{
this.reconnectTimer.Start();
this.heartbeatTimer.Stop();
}
}
catch (Exception)
{
this.heartbeatTimer.Stop();
throw;
}
}, null);

2.2 发送与接收数据(与客户端类似)

三.运行示例

四.总结

假如上述描述,或者代码逻辑中有任何问题,希望各位大神帮忙指出来,谢谢!

其中需要注意的地方如下:

4.1.在异步接收数据的时候,因为接收到的数据大小是不确定的,所以暂定每次只接收1024字节,根据Available判断,如果接收到的数据大于1024字节,则依次拼接得到的数据。

4.2 在服务端中,每次接收到1024字节的byte[]不能定义成全局变量,而需要与每个Socket客户端一一对应,否则再接收来自多个客户端的消息时会出错。(这边我理解是这样)

源码下载地址如下:AsyncSocketDemo.rar

c#之异步Socket通信的更多相关文章

  1. Python简易聊天工具-基于异步Socket通信

    继续学习Python中,最近看书<Python基础教程>中的虚拟茶话会项目,觉得很有意思,自己敲了一遍,受益匪浅,同时记录一下. 主要用到异步socket服务客户端和服务器模块asynco ...

  2. JAVA基础知识之网络编程——-基于AIO的异步Socket通信

    异步IO 下面摘子李刚的<疯狂JAVA讲义> 按照POSIX标准来划分IO,分为同步IO和异步IO.对于IO操作分为两步,1)程序发出IO请求. 2)完成实际的IO操作. 阻塞IO和非阻塞 ...

  3. 使用 boost.asio 简单实现 异步Socket 通信

     客户端: class IPCClient { public: IPCClient(); ~IPCClient(); bool run(); private: bool connect(); bool ...

  4. 第10章 同步设备I/O和异步设备I/O(4)_利用I/O完成端口实现Socket通信

    I/O完成端口原理见上一篇(可点击这里) 10.5.4.4 利用I/O完成端口实现Socket通信 (1)Accept和AcceptEx流程的比较 ①采用accept方式的流程示意图如下(普通的阻塞函 ...

  5. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-介绍

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  6. .NET开源高性能Socket通信中间件Helios介绍及演示

    一:Helios是什么 Helios是一套高性能的Socket通信中间件,使用C#编写.Helios的开发受到Netty的启发,使用非阻塞的事件驱动模型架构来实现高并发高吞吐量.Helios为我们大大 ...

  7. GJM :异步Socket [转载]

    原帖地址:http://blog.csdn.net/awinye/article/details/537264 原文作者:Awinye 目录(?)[-] 转载请原作者联系 Overview of So ...

  8. C# Socket系列三 socket通信的封包和拆包

    通过系列二 我们已经实现了socket的简单通信 接下来我们测试一下,在时间应用的场景下,我们会快速且大量的传输数据的情况! class Program { static void Main(stri ...

  9. .net平台下C#socket通信(上)

    在开始介绍socket前先补充补充基础知识,在此基础上理解网络通信才会顺理成章,当然有基础的可以跳过去了.都是废话,进入正题. TCP/IP:Transmission Control Protocol ...

随机推荐

  1. python中Properties的一些小用法

    property最大的用处就是可以为一个属性制定getter,setter,delete和doc,他的函数原型为: def __init__(self, fget=None, fset=None, f ...

  2. MariaDB/MySQL中的变量

    在MySQL/MariaDB中有好几种变量类型:用户自定义变量.系统变量.一般的临时变量(即本地变量,或称为局部变量). 1.用户变量 用户变量是基于会话的,也是基于用户的,所以我觉得称之为会话变量更 ...

  3. Beta 第一天

    一.今日任务 重新熟悉整体项目 对整个项目在未来的beta冲刺中进程有一个合理的规划 由于我们送出的是一个负责前端的成员,引入的也是一个负责前端工作的女生,(女生做起美工比起男生更加得心应手吧)所以我 ...

  4. 第1次作业:小菜鸟的平凡IT梦

    #1.结缘计算机的始末 ##1.1与计算机相识的几年 作为一个95后,出生在一个互联网开始兴盛的时代.我记得小学的时候,开始知道电脑这个东西,学校有了机房,开始有了所谓的电脑课.那时候计算机对于我来说 ...

  5. Alpha冲刺Day9

    Alpha冲刺Day9 一:站立式会议 今日安排: 经过为期5天的冲刺,基本完成企业人员模块的开发.因第三方机构与企业存在委托的关系.第三方人员对于风险的自查.风险列表的展示以及自查风险的统计展示(包 ...

  6. Alpha冲刺第十二天

    Alpha冲刺第十二天 站立式会议 项目进展 项目核心功能,如学生基本信息管理模块,学生信用信息模块,奖惩事务管理模块等等都已完成,测试工作大体结束. 问题困难 项目结束后对项目的阶段性总结缺乏一定的 ...

  7. 第九条:覆盖equals方法时总要覆盖hashCode方法

    Object类的hashCode方法: public native int hashCode();   是一个本地方法. 其中这个方法的主要注释如下: Whenever it is invoked o ...

  8. 再议Python协程——从yield到asyncio

    协程,英文名Coroutine.前面介绍Python的多线程,以及用多线程实现并发(参见这篇文章[浅析Python多线程]),今天介绍的协程也是常用的并发手段.本篇主要内容包含:协程的基本概念.协程库 ...

  9. ajax 操作

    ajax 操作 ajax呢,就是要做到在神不知鬼不觉的情况之下给服务端发送请求. ajax能干啥哩? 这,,,,: 利用AJAX可以做:1.注册时,输入用户名自动检测用户是否已经存在.2.登陆时,提示 ...

  10. springboot多模块项目下,子模块调用报错:程序包xxxxx不存在

    今天在用springboot搭建多模块项目,结构中有一个父工程Parent  一个通用核心工程core 以及一个项目工程A 当我在工程A中引入core时,没有问题,maven install正常 当我 ...