[C#]Socket通信BeginReceive异步接收数据何时回调Callback
原文地址:http://www.cnblogs.com/wangtonghui/p/3277303.html
最近在做服务器压力测试程序。
接触了一段时间Socket异步通讯,发现自己对BeginReceive什么时候回调产生了错误的理解。之前我一直以为异步接收数据只有当Buffer被填满的时候才会回调。如果这样当服务端的Buffer大于客户端发送的数据时,客户端发送的数据就不会得到及时的处理(当Buffer填满时才处理)。这显然是不合情理的,于是我做了如下测试:
服务端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets; namespace SocketServer
{
class Program
{
//服务端buffer为4字节
static byte[] buffer = new byte[4];
static void Main(string[] args)
{
Console.WriteLine("[Server]");
try
{
Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketServer.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4444));
socketServer.Listen(int.MaxValue);
Console.WriteLine("服务端已启动,等待连接...");
//接收连接
Socket ts = socketServer.Accept();
Console.WriteLine("客户端已连接"); //开始异步接收
ts.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), ts);
Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
} static void ReceiveCallback(IAsyncResult result)
{
Socket ts = (Socket)result.AsyncState;
ts.EndReceive(result);
result.AsyncWaitHandle.Close();
Console.WriteLine("收到消息:{0}", Encoding.ASCII.GetString(buffer)); //清空数据,重新开始异步接收
buffer = new byte[buffer.Length];
ts.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), ts);
}
}
}客户端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets; namespace SocketClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("[Client]");
try
{
Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketClient.Connect(IPAddress.Parse("127.0.0.1"), 4444);
Console.WriteLine("发送消息:");
//获取发送内容
string sendStr = Console.ReadLine();
while (!(sendStr.ToLower() == "q"))
{
Console.WriteLine("发送消息:");
//同步发送数据
socketClient.Send(Encoding.ASCII.GetBytes(sendStr));
sendStr = Console.ReadLine();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("按任意键退出");
Console.ReadKey();
}
}
}
}
可以看到服务端采用异步接收的方式,每次接收不超过4个字节。客户端不限制一次发送数据的字节数。(备注:1.先运行服务端后运行客户端 2.发送数据采用ASCII编码,每个字符占用1个字节 3.Socket.ReceiveBufferSize应当大于Buffer长度,否则会得到其他结果)
测试结果:
1.发送数据长度与接收Buffer长度一致,接收到所有数据回调;
2.发送数据长度大于接收Buffer长度,Buffer填满时回调,数据接收完时回调;
3.发送数据长度小于接收Buffer长度,数据接收完时回调;
如果想要手动强制使BeginReceive回调,MSDN提供的方法是:
若要取消挂起的 BeginReceive,请调用 Close 方法。
[C#]Socket通信BeginReceive异步接收数据何时回调Callback的更多相关文章
- iOS开发之Socket通信实战--Request请求数据包编码模块
实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...
- socket tcp使用recv接收数据时,返回errno错误代码88
原因:就是recv函数的第一个参数不是可用的,也就是第一个参数不是建立连接时返回的文件描述符. 解决方法:xxx
- c#之异步Socket通信
0.基于上一篇的c#之Socket(同步)通信,在几个大神评论之后,发现是有挺多地方不足的,所以写了一个改进版本的基于c#的异步Socket通信.再加深一下对Socket的使用和理解.其中客户端和服务 ...
- JAVA ANDROID SOCKET通信检测(SERVER)连接是否断开
Pre 解决思路 代码后记: 客户端app上的部分代码 调用: 服务器上: 客户端判断服务器是否还活着代码: PRE 在利用socket写通讯程序的时候,想检测服务器是否还活着. 从网上找了很多资料, ...
- STM32 ucosii 串口接收数据 遇到的问题及解决思路
写一个程序,用到了ucos ii ,串口在中断中接收数据(一包数据 8个字节 包含: 1byte包头 5byte数据 1byte校验和 1byte 包尾 ) ,数据由上位机每隔500ms发送一次,在串 ...
- socket 异步接收连接和接收数据
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- socket 异步 发送 接收 数据
Socket socketClints = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); / ...
- 使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)
原文:使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置) 在上一篇中说到了Silverlight下的Socket通信,在最后的时候说到本篇将会结合地图. ...
- 第10章 同步设备I/O和异步设备I/O(4)_利用I/O完成端口实现Socket通信
I/O完成端口原理见上一篇(可点击这里) 10.5.4.4 利用I/O完成端口实现Socket通信 (1)Accept和AcceptEx流程的比较 ①采用accept方式的流程示意图如下(普通的阻塞函 ...
随机推荐
- 抽屉之Tornado实战(1)--分析与架构
抽屉之Tornado实战(1)--分析与架构 项目模拟地址:http://dig.chouti.com/ 知识点应用: AJAX 用于偷偷发请求 原生ajax jQuery ajax($.aj ...
- PopupMenu动态创建菜单
1.TPopupMenu一条横线在Caption输入一个'-'就可以了.2.在Caption输入名字之后加入一个&就可以不显示快捷键,比如: 退出& 这样退出按钮的快捷键就不会显示出 ...
- Django实现邮件发送功能
首先申请邮箱并在设置中申请到授权码,授权码的目的仅仅是让你有权限发邮件,但是不能登录到邮箱进行修改,发送邮件时,可以代替密码 1,配置文件settings.py #邮件服务配置文件 EMAIL_USE ...
- Python 字符串常用方法总结
明确:对字符串的操作方法都不会改变原来字符串的值 1,去掉空格和特殊符号 name.strip() 去掉空格和换行符 name.strip('xx') 去掉某个字符串 name.lstrip() ...
- ASCLL码中的一些小知识
其次要记住asill值中 65是A 97是a A与a之间相隔32,用int转换后再用char转换回来. char b = s.charAt(i);为字符串转换成一个一个的.
- 更改配置:远程访问gitlab的postgresql数据库
作为这篇文章的补充: 将gitlab中的postgresql数据库开通远程访问 https://www.cnblogs.com/andy9468/p/10609682.html 替代(二)中的2.3. ...
- 万恶之源 - Python模块一
序列化 我们今天学习下序列化,什么是序列化呢? 将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化. 为什么要有序列化模块: 比如,我们在python代码中计算的一个数据需要给另外一段程序使用 ...
- echarts 实现tooltip双栏效果
实现效果如下: 代码: //option tooltip: { trigger: 'axis', axisPointer: { label: { show: true, fontSize: 15 } ...
- python字符串前带u,r,b的含义
1. https://www.cnblogs.com/yanglang/p/7416889.html 2.https://blog.csdn.net/teavamc/article/details/7 ...
- seq2seq和attention应用到文档自动摘要
一.摘要种类 抽取式摘要 直接从原文中抽取一些句子组成摘要.本质上就是个排序问题,给每个句子打分,将高分句子摘出来,再做一些去冗余(方法是MMR)等.这种方式应用最广泛,因为比较简单.经典方法有Lex ...

