引言

项目中用到了Socket,这里做个控制台小示例记录一下。

Client

客户端的Receive用了异步方法,保持长连接,可以随时发送消息和响应服务端的消息,如下

  1. static string ClientReceiveMessage = "";
  2. static byte[] receivedBytes = new byte[];
  3. static void Main(string[] args)
  4. {
  5.  
  6. IPHostEntry ipHost = Dns.Resolve("127.0.0.1");
  7. IPAddress ipAddress = ipHost.AddressList[];
  8. IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, );
  9.  
  10. string sendingMessage = "Hello World Socket Test";
  11.  
  12. Console.WriteLine("Creating message: Hello World Socket Test");
  13.  
  14. Socket sender = new Socket(AddressFamily.InterNetwork,
  15. SocketType.Stream,
  16. ProtocolType.Tcp);
  17. sender.Connect(ipEndPoint);
  18.  
  19. sender.BeginReceive(receivedBytes, , receivedBytes.Length, , ReceiveCallback, sender);
  20.  
  21. while (true)
  22. {
  23. sendingMessage = Console.ReadLine();
  24. byte[] forwardMessage = Encoding.ASCII.GetBytes(sendingMessage + "[FINAL]");
  25. sender.Send(forwardMessage);
  26. }
  27. }
  28.  
  29. private static void ReceiveCallback(IAsyncResult ar)
  30. {
  31. Socket client = (Socket)ar.AsyncState;
  32.  
  33. int totalBytesReceived = client.EndReceive(ar);
  34.  
  35. if (totalBytesReceived > )
  36. {
  37.  
  38. ClientReceiveMessage += Encoding.ASCII.GetString(receivedBytes, , totalBytesReceived);
  39. if (ClientReceiveMessage.IndexOf("[FINAL]", StringComparison.Ordinal) > -)
  40. {
  41. Console.WriteLine(ClientReceiveMessage);
  42. ClientReceiveMessage = "";
  43. }
  44.  
  45. client.BeginReceive(receivedBytes, , receivedBytes.Length, , new AsyncCallback(ReceiveCallback), client);
  46. }
  47. else
  48. {
  49. Console.WriteLine("服务端结束不再发送消息!" );
  50. ClientReceiveMessage = "";
  51. }
  52.  
  53. }

Server

服务端循环异步Accept,可以接收多个client消息,并且马上回复。

  1. static ManualResetEvent allDone = new ManualResetEvent(false);
  2. static void Main(string[] args)
  3. {
  4.  
  5. Socket listener = new Socket(AddressFamily.InterNetwork,
  6. SocketType.Stream,
  7. ProtocolType.Tcp);
  8. listener.Bind(new IPEndPoint(IPAddress.Any, ));
  9. listener.Listen();
  10.  
  11. while (true)
  12. {
  13. allDone.Reset();
  14. listener.BeginAccept(ar =>
  15. {
  16. allDone.Set();
  17.  
  18. Socket MyServer = (Socket)ar.AsyncState;
  19.  
  20. Socket service = MyServer.EndAccept(ar);
  21.  
  22. byte[] receivedBytes = new byte[];
  23.  
  24. while (true)
  25. {
  26. string receivedValue = string.Empty;
  27. int numBytes = service.Receive(receivedBytes);
  28. receivedValue += Encoding.ASCII.GetString(receivedBytes,, numBytes);
  29.  
  30. if (receivedValue.IndexOf("[FINAL]", StringComparison.Ordinal) > -)
  31. {
  32. Console.WriteLine("Received value: {0} from " + service.RemoteEndPoint, receivedValue);
  33. string replyValue = "Message successfully received.[FINAL]";
  34. byte[] replyMessage = Encoding.ASCII.GetBytes(replyValue);
  35. service.Send(replyMessage);
  36. }
  37. }
  38. }, listener);
  39.  
  40. allDone.WaitOne();
  41. }

注意事项

1.Socket的Receive方法响应次数,是以缓冲数组的大小划分。如果数组大小为1024,消息为2048,Receive将会触发两次。作为接收方无法通过Receive来确定是否已完整接收,所以要对消息另作处理,例如在消息中增加[FINAL]来确定消息已发送完毕。

2.如果没有消息发送,接收方Receive方法会一直等待。但如果发送方调用Shutdown(SocketShutdown.Send)方法,接收方的Receive会马上返回0,所以在非来回传递消息的情况下,可以Shutdown方法来实现消息发送完毕。

3.可以设置ReceiveTimeout的值,超时会抛出异常,然而只能作用于Receive方法,对BeginReceive无效。

【.Net】Socket小示例的更多相关文章

  1. ReactNative新手学习之路06滚动更新ListView数据的小示例

    本节带领大家学习使用ListView 做一个常用的滚动更新数据示例: 知识点: initialListSize={200} 第一次加载多少数据行 onEndReached={this.onEndRea ...

  2. MVC客户端验证的小示例

    MVC客户端验证的小示例 配置客户端验证的可用性: <configuration> <appSettings>  <add key="ClientValidat ...

  3. 多线程Java Socket编程示例

    package org.merit.test.socket; import java.io.BufferedReader; import java.io.IOException; import jav ...

  4. CentOS7 安装 RocketMQ 实践和小示例

    CentOS7 安装 RocketMQ 实践和小示例 1.通过 SSH 工具(比如 XShell)连接到 CentOS7 服务器上: 2.进入到 /usr/local 目录中: cd /usr/loc ...

  5. Socket 编程示例(二)

    利用晚上这点闲暇时间,写了一个Socket通信的小实例,该实例包含服务器端和客户端.其基本工作流程是:当服务器启动服务以后,客户端进行连接,如果连接成功,则用户可以在发送消息框中输入待发送的消息,然后 ...

  6. java nio socket使用示例

    这个示例,实现一个简单的C/S,客户端向服务器端发送消息,服务器将收到的消息打印到控制台,并将该消息返回给客户端,客户端再打印到控制台.现实的应用中需要定义发送数据使用的协议,以帮助服务器解析消息.本 ...

  7. Highcharts入门小示例

    一.创建条形图 1.创建div容器 <div id="container" style="min-width:800px;height:400px"> ...

  8. Http与Socket小谈

    http与socket是网络编程中最为重要的概念,不管是客户端还是服务端,都是最为重要的部分,以下简述两者的关系和区别(个人见解). Http 定义 基于应用层的超文本传输协议.通常承载于TCP/IP ...

  9. 多线程Java Socket编程示例(转)

    这篇做为学习孙卫琴<<Java网络编程精解>>的学习笔记吧.其中采用Java 5的ExecutorService来进行线程池的方式实现多线程,模拟客户端多用户向同一服务器端发送 ...

随机推荐

  1. Linux(6)- redis发布订阅/持久化/主从复制/redis-sentinel/redis-cluster、nginx入门

    一.redis发布订阅 Redis 通过 PUBLISH .SUBSCRIBE 等命令实现了订阅与发布模式. 其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个 ...

  2. .net截取字符串

    string s=abcdeabcdeabcdestring[] sArray1=s.Split(new char[3]{c,d,e}) ;foreach(string i in sArray1)Co ...

  3. python数据类型及其操作

    一.数字 常用类型:int,float age = 10  # int型 salary = 3000.5  # float型 进制: 二进制: 11 = 1*21 + 1*20 = 3 八进制: 11 ...

  4. Python高阶函数-闭包

    高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 在这里我们首先回忆一下python代码运行的时候遇到函数是怎么做的. 从python解释器开始执行之后,就在内存中开辟了一个空间 每当 ...

  5. kmp模板 && 扩展kmp模板

    kmp模板: #include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; ...

  6. MySQL-Last_Errno: 1594

    故障现象  :MySQL slave所在机器自动重启,启动MySQL后,查看主从信息如下: Error_code: 1594   mysql> show slave status \G . ro ...

  7. 20145235李涛《网络对抗》Exp5 MSF基础应用

    基础问答 用自己的话解释什么是exploit,payload,encode? exploit:相当于搬运工,把攻击代码传送到靶机中. payload:相当于shellcode. encode:相当于包 ...

  8. Mac & Xcode 技巧

    1.Xcode 删除过期的Provisioning Profile文件 解决:Xcode 中所有的Provisioning Profile文件路径,都在 ~/Library/MobileDevice/ ...

  9. SQLite教程

    SQLite教程 http://www.runoob.com/sqlite/sqlite-date-time.html SQLite管理工具http://www.sqliteexpert.com/do ...

  10. ARM协处理器CP15寄存器详解【转】

    本文转载i自;https://blog.csdn.net/gameit/article/details/13169405 用于系统存储管理的协处理器CP15   MCR{cond}     copro ...