【.Net】Socket小示例
引言
项目中用到了Socket,这里做个控制台小示例记录一下。
Client
客户端的Receive用了异步方法,保持长连接,可以随时发送消息和响应服务端的消息,如下
- static string ClientReceiveMessage = "";
- static byte[] receivedBytes = new byte[];
- static void Main(string[] args)
- {
- IPHostEntry ipHost = Dns.Resolve("127.0.0.1");
- IPAddress ipAddress = ipHost.AddressList[];
- IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, );
- string sendingMessage = "Hello World Socket Test";
- Console.WriteLine("Creating message: Hello World Socket Test");
- Socket sender = new Socket(AddressFamily.InterNetwork,
- SocketType.Stream,
- ProtocolType.Tcp);
- sender.Connect(ipEndPoint);
- sender.BeginReceive(receivedBytes, , receivedBytes.Length, , ReceiveCallback, sender);
- while (true)
- {
- sendingMessage = Console.ReadLine();
- byte[] forwardMessage = Encoding.ASCII.GetBytes(sendingMessage + "[FINAL]");
- sender.Send(forwardMessage);
- }
- }
- private static void ReceiveCallback(IAsyncResult ar)
- {
- Socket client = (Socket)ar.AsyncState;
- int totalBytesReceived = client.EndReceive(ar);
- if (totalBytesReceived > )
- {
- ClientReceiveMessage += Encoding.ASCII.GetString(receivedBytes, , totalBytesReceived);
- if (ClientReceiveMessage.IndexOf("[FINAL]", StringComparison.Ordinal) > -)
- {
- Console.WriteLine(ClientReceiveMessage);
- ClientReceiveMessage = "";
- }
- client.BeginReceive(receivedBytes, , receivedBytes.Length, , new AsyncCallback(ReceiveCallback), client);
- }
- else
- {
- Console.WriteLine("服务端结束不再发送消息!" );
- ClientReceiveMessage = "";
- }
- }
Server
服务端循环异步Accept,可以接收多个client消息,并且马上回复。
- static ManualResetEvent allDone = new ManualResetEvent(false);
- static void Main(string[] args)
- {
- Socket listener = new Socket(AddressFamily.InterNetwork,
- SocketType.Stream,
- ProtocolType.Tcp);
- listener.Bind(new IPEndPoint(IPAddress.Any, ));
- listener.Listen();
- while (true)
- {
- allDone.Reset();
- listener.BeginAccept(ar =>
- {
- allDone.Set();
- Socket MyServer = (Socket)ar.AsyncState;
- Socket service = MyServer.EndAccept(ar);
- byte[] receivedBytes = new byte[];
- while (true)
- {
- string receivedValue = string.Empty;
- int numBytes = service.Receive(receivedBytes);
- receivedValue += Encoding.ASCII.GetString(receivedBytes,, numBytes);
- if (receivedValue.IndexOf("[FINAL]", StringComparison.Ordinal) > -)
- {
- Console.WriteLine("Received value: {0} from " + service.RemoteEndPoint, receivedValue);
- string replyValue = "Message successfully received.[FINAL]";
- byte[] replyMessage = Encoding.ASCII.GetBytes(replyValue);
- service.Send(replyMessage);
- }
- }
- }, listener);
- allDone.WaitOne();
- }
注意事项
1.Socket的Receive方法响应次数,是以缓冲数组的大小划分。如果数组大小为1024,消息为2048,Receive将会触发两次。作为接收方无法通过Receive来确定是否已完整接收,所以要对消息另作处理,例如在消息中增加[FINAL]来确定消息已发送完毕。
2.如果没有消息发送,接收方Receive方法会一直等待。但如果发送方调用Shutdown(SocketShutdown.Send)方法,接收方的Receive会马上返回0,所以在非来回传递消息的情况下,可以Shutdown方法来实现消息发送完毕。
3.可以设置ReceiveTimeout的值,超时会抛出异常,然而只能作用于Receive方法,对BeginReceive无效。
【.Net】Socket小示例的更多相关文章
- ReactNative新手学习之路06滚动更新ListView数据的小示例
本节带领大家学习使用ListView 做一个常用的滚动更新数据示例: 知识点: initialListSize={200} 第一次加载多少数据行 onEndReached={this.onEndRea ...
- MVC客户端验证的小示例
MVC客户端验证的小示例 配置客户端验证的可用性: <configuration> <appSettings> <add key="ClientValidat ...
- 多线程Java Socket编程示例
package org.merit.test.socket; import java.io.BufferedReader; import java.io.IOException; import jav ...
- CentOS7 安装 RocketMQ 实践和小示例
CentOS7 安装 RocketMQ 实践和小示例 1.通过 SSH 工具(比如 XShell)连接到 CentOS7 服务器上: 2.进入到 /usr/local 目录中: cd /usr/loc ...
- Socket 编程示例(二)
利用晚上这点闲暇时间,写了一个Socket通信的小实例,该实例包含服务器端和客户端.其基本工作流程是:当服务器启动服务以后,客户端进行连接,如果连接成功,则用户可以在发送消息框中输入待发送的消息,然后 ...
- java nio socket使用示例
这个示例,实现一个简单的C/S,客户端向服务器端发送消息,服务器将收到的消息打印到控制台,并将该消息返回给客户端,客户端再打印到控制台.现实的应用中需要定义发送数据使用的协议,以帮助服务器解析消息.本 ...
- Highcharts入门小示例
一.创建条形图 1.创建div容器 <div id="container" style="min-width:800px;height:400px"> ...
- Http与Socket小谈
http与socket是网络编程中最为重要的概念,不管是客户端还是服务端,都是最为重要的部分,以下简述两者的关系和区别(个人见解). Http 定义 基于应用层的超文本传输协议.通常承载于TCP/IP ...
- 多线程Java Socket编程示例(转)
这篇做为学习孙卫琴<<Java网络编程精解>>的学习笔记吧.其中采用Java 5的ExecutorService来进行线程池的方式实现多线程,模拟客户端多用户向同一服务器端发送 ...
随机推荐
- Linux(6)- redis发布订阅/持久化/主从复制/redis-sentinel/redis-cluster、nginx入门
一.redis发布订阅 Redis 通过 PUBLISH .SUBSCRIBE 等命令实现了订阅与发布模式. 其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个 ...
- .net截取字符串
string s=abcdeabcdeabcdestring[] sArray1=s.Split(new char[3]{c,d,e}) ;foreach(string i in sArray1)Co ...
- python数据类型及其操作
一.数字 常用类型:int,float age = 10 # int型 salary = 3000.5 # float型 进制: 二进制: 11 = 1*21 + 1*20 = 3 八进制: 11 ...
- Python高阶函数-闭包
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 在这里我们首先回忆一下python代码运行的时候遇到函数是怎么做的. 从python解释器开始执行之后,就在内存中开辟了一个空间 每当 ...
- kmp模板 && 扩展kmp模板
kmp模板: #include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; ...
- MySQL-Last_Errno: 1594
故障现象 :MySQL slave所在机器自动重启,启动MySQL后,查看主从信息如下: Error_code: 1594 mysql> show slave status \G . ro ...
- 20145235李涛《网络对抗》Exp5 MSF基础应用
基础问答 用自己的话解释什么是exploit,payload,encode? exploit:相当于搬运工,把攻击代码传送到靶机中. payload:相当于shellcode. encode:相当于包 ...
- Mac & Xcode 技巧
1.Xcode 删除过期的Provisioning Profile文件 解决:Xcode 中所有的Provisioning Profile文件路径,都在 ~/Library/MobileDevice/ ...
- SQLite教程
SQLite教程 http://www.runoob.com/sqlite/sqlite-date-time.html SQLite管理工具http://www.sqliteexpert.com/do ...
- ARM协处理器CP15寄存器详解【转】
本文转载i自;https://blog.csdn.net/gameit/article/details/13169405 用于系统存储管理的协处理器CP15 MCR{cond} copro ...