0.虽然之前在项目中也有用过Socket,但始终不是自己搭建的,所以对Server,Clinet端以及心跳,断线重连总没有很深入的理解,现在自己搭建了一遍加深一下理解。

服务端使用WPF界面,客户端使用控制台。实现了心跳,断线重连,一个服务端对应多个客户端的功能。

一.服务端

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

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

1.2 当有客户端成功连接,则会通过Accept方法生产一个新的Socket实例;此时可开启心跳定时器,并开启一个线程接收消息。

  1. //开启一个线程监听客户端
  2. Thread thd = new Thread(new ThreadStart(ListenSocket));
  3. thd.Start();
  4.  
  5. /// <summary>
  6. /// 开始监听
  7. /// </summary>
  8. private void ListenSocket()
  9. {
  10. try
  11. {
  12. while (true)
  13. {
  14. Socket _socket = socketServer.Accept();
  15.  
  16. //开始心跳
  17. System.Timers.Timer heartbeatTimer = new System.Timers.Timer();
  18. heartbeatTimer.Interval = ;
  19. heartbeatTimer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => heartbeatTimerIsUp(s, e, _socket));
  20. heartbeatTimer.Start();
  21.  
  22. Thread thdReceive = new Thread(new ParameterizedThreadStart(thdRevMethod));
  23. thdReceive.Start(_socket);
  24. }
  25. }
  26. catch (Exception ex)
  27. {
  28. MessageBox.Show("程序出现异常:" + ex);
  29. }
  30. }

1.3 接收消息与发送消息的代码如下

  1. /// <summary>
  2. /// 接收消息
  3. /// </summary>
  4. /// <param name="obj"></param>
  5. private void thdRevMethod(object obj)
  6. {
  7. Socket _socket = obj as Socket;
  8. try
  9. {
  10. while (true)
  11. {
  12. byte[] resByte = new byte[];
  13. int resInt = _socket.Receive(resByte);
  14. if (resInt > )
  15. {
  16. string res = Encoding.Default.GetString(resByte, , resInt);///接收消息后操作
  17. }
  18. }
  19. }
  20. catch (SocketException sex)
  21. {
  22. if (sex.SocketErrorCode == SocketError.ConnectionReset)
  23. {
  24. //当客户端断开连接,从客户端列表中移除该客户端
  25. }
  26. }
  27. catch (Exception ex)
  28. {
  29. MessageBox.Show("程序出现异常:" + ex);
  30. }
  31. }
  32.  
  33. /// <summary>
  34. /// 发送消息
  35. /// </summary>
  36. /// <param name="msg"></param>
  37. /// <param name="ipAndPord"></param>
  38. public bool sendMsg(string msg,string ipAndPord)
  39. {
  40. try
  41. {
  42. Socket _socket = socketTimerDic.SingleOrDefault(r => string.Equals(r.Key.RemoteEndPoint.ToString(), ipAndPord)).Key;
  43. if (_socket != null)
  44. {
  45. byte[] byteStr = Encoding.Default.GetBytes(msg);
  46. _socket.Send(byteStr);
  47. return true;
  48. }
  49. else
  50. {
  51. return false;
  52. }
  53. }
  54. catch (Exception)
  55. {
  56. return false;
  57. }
  58. }

二.客户端

2.1 先创建一个Socket实例,并连接到服务端所在的ip端口;连接成功后开启心跳定会器并开启发送和接收消息的两个线程。

  1. // 新建客户端实例,并连接到服务端所在的端口号
  2. socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  3.  
  4. socketClient.Connect("127.0.0.1", );
  5. Console.WriteLine("成功连接到服务端");
  6. heartbeatTimer.Start();
  7.  
  8. //开启一个线程发送消息
  9. Thread thdSend = new Thread(new ThreadStart(thdSendMethod));
  10. thdSend.Start();
  11.  
  12. //开启一个线程接收信息
  13. Thread thdRev = new Thread(new ThreadStart(thdRevMethod));
  14. thdRev.Start();

2.2 发送消息和接收消息的代码如下,当服务端断开会在接收消息的线程中触发sex.SocketErrorCode == SocketError.ConnectionReset的异常,此时捕获到后开启重连定时器即可

  1. /// <summary>
  2. /// 接收消息
  3. /// </summary>
  4. private static void thdRevMethod()
  5. {
  6. try
  7. {
  8. while (true)
  9. {
  10. byte[] resByte = new byte[];
  11. int resInt = socketClient.Receive(resByte);
  12. if (resInt > )
  13. {
  14. Console.WriteLine(Encoding.Default.GetString(resByte,, resInt));
  15. }
  16. }
  17.  
  18. }
  19. catch (SocketException sex)
  20. {
  21. if (sex.SocketErrorCode == SocketError.ConnectionReset)
  22. {
  23. Console.WriteLine("服务端断开!5s后重连!");
  24. reconnectTimer.Start();
  25. heartbeatTimer.Stop();
  26. }
  27. }
  28. catch (Exception ex)
  29. {
  30. Console.WriteLine("程序出现异常:" + ex);
  31. heartbeatTimer.Stop();
  32. }
  33. }
  34.  
  35. //发送信息
  36. private static void thdSendMethod()
  37. {
  38. try
  39. {
  40. while (true)
  41. {
  42. string res = Console.ReadLine();
  43. byte[] resByte = Encoding.Default.GetBytes(res);
  44. socketClient.Send(resByte);
  45. }
  46. }
  47. catch (Exception ex)
  48. {
  49. Console.WriteLine("程序出现异常:" + ex);
  50. heartbeatTimer.Stop();
  51. }
  52. }

三.运行示例

四..总结

假如代码中有错误的地方,希望可以帮忙指出来改之。

其中要注意的地方如下:
1.WPF关闭窗口后,需要通过 Environment.Exit(0);来结束掉当前整个服务端进程,否则Socket开启的接收和发送进程将还在,客户端也不会检测到服务端断开。

2.在SocketException中捕获异常sex.SocketErrorCode == SocketError.ConnectionReset时说明客户端/服务端连接断开了,需要进行重连等操作。

3.在接收到消息时候需要用GetString(byte[] bytes, int index, int count)指定长度,而不该使用GetString(byte[] bytes),否则可能出现很多空格。

4.定时器假如需要传递参数,可以通过设置全局变量,或者(s, e) => heartbeatTimerIsUp(s, e, _socket)单独传递一个变量到方法中。

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

C#之Socket通信的更多相关文章

  1. 我看不下去鸟。。。。Java和C#的socket通信真的简单吗?

    这几天在博客园上看到好几个写Java和C#的socket通信的帖子.但是都为指出其中关键点. C# socket通信组件有很多,在vs 使用nuget搜索socket组件有很多类似的.本人使用的是自己 ...

  2. php简单实现socket通信

    socket通信的原理在这里就不说了,它的用途还是比较广泛的,我们可以使用socket来做一个API接口出来,也可以使用socket来实现两个程序之间的通信,我们来研究一下在php里面如何实现sock ...

  3. Socket通信类

    package com.imooc; import java.io.BufferedReader; import java.io.IOException; import java.io.InputSt ...

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

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

  5. socket通信

    socket通信 一:socket基于Tcp连接,数据传输有保证 二:socket连接的建立过程: 1:服务器监听 2:客户端发出请求 3:建立连接 4:通信 三:一个简单的例子:服务器端每隔一段时间 ...

  6. Android之Socket通信、List加载更多、Spinner下拉列表

    Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务 ...

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

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

  8. iOS开发之Socket通信实战--Request请求数据包编码模块

    实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...

  9. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  10. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-完整应用例子-在线聊天室系统-下载配置

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

随机推荐

  1. RocketMQ与kafka对比(官方)

    淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用Mysql作为消息存储媒介,可完全水平扩容,为了进一步降低成本,我们认为存储部分可以进一步优化,2011年初,Linkin开源了Kaf ...

  2. Spring @AfterReturning 总是返回null

    在学习Spring Aop时,遇到一个问题,当 @Around(环绕通知)与 @AfterReturning(后置通知)共存 时,@AfterReturning 通过属性 returning = &q ...

  3. python格式化输出基础知识(2)

    ---恢复内容开始--- 一:请输入名片  (姓名,年龄,职业,爱好)设计名片 name=input('你的名字')age=input('你的年龄')job=input('你的工作')hobbie=i ...

  4. WordPress用键盘左右方向键来查看上一篇和下一篇文章

    通过键盘来查看上下篇文章是不是很方便,这个其实就是条用键盘所对应的ASCII码来实现的,比如左右方向键所对应的ASCII码就是37和39,下面来看看实现怎么实现这个功能: 1.加载jQury库,当然很 ...

  5. 使用localtunne一分钟搞定微信公众号接入

      记得15年那个刚刚进入工作的时候,公司有个微信公众号的项目,那个时候微信官方没有什么调试工具,也没有什么比较好的本地调试工具.当时有个功能需要调用微信JSSDK里面的扫一扫的功能.由于本地不能调试 ...

  6. 云计算---openstack实例共享80、443端口

    前言 因为openstack使用的是apache,所以不能共享80端口,但创建的许多云主机,虽然可以通过rinetd进行跳转,但有时需要直接访问80端口,所以这里我们选择包含了nginx的openre ...

  7. Linux中查看进程树

    pstree -p 查看当前的shell的进程和执行shell脚本的子进程的方法:echo $$

  8. smoking的安装和配置

    yum install -y perl perl-Net-Telnet perl-Net-DNS perl-LDAP perl-libwww-perl perl-IO-Socket-SSL perl- ...

  9. ER图

    E-R图也称实体-联系图(Entity Relationship Diagram), 提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型. 它是描述现实世界概念结构模型的有效方法.是表示 ...

  10. sublime COMMAND + B 调用 python3 运行

    用sublime写了python3的代码,COMMAND + B运行调用 PYTHON3 我们先来新建一个sublime build system 然后自动打开了一个文本,清空并写入以下内容: { & ...