原文地址: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的更多相关文章

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

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

  2. socket tcp使用recv接收数据时,返回errno错误代码88

    原因:就是recv函数的第一个参数不是可用的,也就是第一个参数不是建立连接时返回的文件描述符. 解决方法:xxx

  3. c#之异步Socket通信

    0.基于上一篇的c#之Socket(同步)通信,在几个大神评论之后,发现是有挺多地方不足的,所以写了一个改进版本的基于c#的异步Socket通信.再加深一下对Socket的使用和理解.其中客户端和服务 ...

  4. JAVA ANDROID SOCKET通信检测(SERVER)连接是否断开

    Pre 解决思路 代码后记: 客户端app上的部分代码 调用: 服务器上: 客户端判断服务器是否还活着代码: PRE 在利用socket写通讯程序的时候,想检测服务器是否还活着. 从网上找了很多资料, ...

  5. STM32 ucosii 串口接收数据 遇到的问题及解决思路

    写一个程序,用到了ucos ii ,串口在中断中接收数据(一包数据 8个字节 包含: 1byte包头 5byte数据 1byte校验和 1byte 包尾 ) ,数据由上位机每隔500ms发送一次,在串 ...

  6. socket 异步接收连接和接收数据

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. socket 异步 发送 接收 数据

    Socket socketClints = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); / ...

  8. 使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)

    原文:使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置) 在上一篇中说到了Silverlight下的Socket通信,在最后的时候说到本篇将会结合地图. ...

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

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

随机推荐

  1. LeetCode 349 Intersection of Two Arrays 解题报告

    题目要求 Given two arrays, write a function to compute their intersection. 题目分析及思路 给定两个数组,要求得到它们之中共同拥有的元 ...

  2. 启动虚拟机提示"Units specified don’t exist SHSUCDX can’t install"

    新建虚拟机快速分区后启动报"Units specified don’t exist SHSUCDX can’t install",试过网上说的 修改BIOS设置方法不起作用 修改虚 ...

  3. java上传文件代码

    import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;impo ...

  4. I2C驱动框架(kernel-2.6.22.6)

    以用i2c通信的实时时钟为例 框架入口源文件:i2c_m41t11.c (可根据入口源文件,再按着框架到内核走一遍) 内核版本:linux_2.6.22.6   硬件平台:JZ2440 以下是驱动框架 ...

  5. 关于安装SVN Service 出错 Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details

    关于安装SVN Service 出错 Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in ...

  6. SHOW STATUS 查看各种类型SQL执行的频率

    通过 SHOW STATUS 可以提供服务器状态信息,也可以使用 mysqladmin extendedstatus 命令获得.SHOW STATUS 可以根据需要显示 session 级别的统计结果 ...

  7. shell 命令 set命令

    set命令输出所有的变量,包括全局变量和局部变量: set-o命令显示bash Shell的所有参数配置信息 set -o nounset              -u                ...

  8. testetest

    resumeLoad renren静态 foolday \ swImg activity01

  9. [js]纯css强制不换行

    要加在li上 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  10. 2019.03.23 Http

    自己也要分清楚  看清楚 request,response 一个是请求  一个是相应 行 头    之间还有个空行    体 HttpRequest请求对象(只读) 当用户访问一个视图函数时,Djan ...