socket通信在使用时被封装很简单,像操作文件一样简单,正是因为简单里面好多细节需要深入研究一下。

  windows下通信有select和iocp方式,select是传统方式,在socket里使用receive send这种方式出现,iocp是一种高效的方式,不会产生过多线程,被socket使用beginreceive和endreceive和这种异步委托方式实现。

  

在开发中,最麻烦的是写接收服务(receive),因为发送方总是不可控的,一个稳定receive服务,需要了解,连接,接收机制,关闭,数据缓冲,错误处理。当然还有最麻烦的包边界问题。连接BeginAccept 是一个新连接必然进入的方法主要是EndAccept得到一个工作的socket(且叫它worksocket,就是与指定客户连接的一个socket),这个worksocket远程地址就是连接的客户端口发出的地址。 这时workSocket != null && workSocket.Connected 是true的。beginReceive 是在接收端循环接收的异步方式(只要这个worksocket不断)它会一直徘徊在beginReceive 和EndReceive中,beginreceive用来从端口缓冲区读到指定缓冲区,(socket通信有二个缓冲区),缓冲区不可能无限的大,所以每次可以读到最大也就是指定缓冲区尺寸<=EndReceive返回的值。

  

    socket关闭,有以下三种情况。

    一,如果客户端口直接关闭,这时服务端在EndReceive时直接抛错,不回有0的返回,只会抛出一个远程连接被关闭了。

    二、如果客户端口调用shutdown 与close而服务端口EndReceive 返回 0(返回0说明远程已经关闭了)这时必须worksocket.shutdown和close方法,如果不及时关闭                      一直返回0,这个连接一直不会断。在beginreceiv中不要用Connected判断,这个状态一直是false,还有Available也是不准的,

        三、如果服务端把一个worksocket先给关闭了(不是整个socket),而客户没有在这之前关闭,程序有崩溃的风险。

    一个高效的发送是客户发送端一直发,而不管状态,(接收状态通过异步方式)

    

  while (B!= ConsoleKey.Q)
{
if (B == ConsoleKey.R)
{
for (int i = ; i < ; i++)
{
byte[] bytes = Encoding.UTF8.GetBytes("欢迎你"+i.ToString());
sender.Send(bytes);
sender.BeginReceive();
}
}
else if (B == ConsoleKey.C)
{
sender.Close(); } B = Console.ReadKey().Key;
}

    接收端异步接收,异步发回状态。也可以同步发回。

    

  try
{
cnt = wsocket.EndReceive(result); if (cnt == )
{
Console.WriteLine(cnt);
wsocket.Shutdown(SocketShutdown.Both);
wsocket.Close();
}
else
{ string str = Encoding.UTF8.GetString(receiveBuf, , cnt);
Console.WriteLine(str);
workSocket.Send(Encoding.UTF8.GetBytes("服务收到"+str)); wsocket.BeginReceive(receiveBuf, , receiveBuf.Length, SocketFlags.None, EndReceive, workSocket);
} }
catch (Exception oe)
{
Console.WriteLine(oe.Message);
}

最后一点客户端并发的发送,服务端接收的数据可能需要解决粘包问题,这个问题,有二种方式处理,一、特殊字符 二、定义包的协议。

    

    

socket 异步通信的一些问题的更多相关文章

  1. socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto

    socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...

  2. Socket异步通信学习三

    接下来是客户端部分,采用同步接收模式,在SocketClient项目中新建了一个SynServer类,用于存放socket服务器代码,和AsynServer类似,主要有4个方法: 有一个全局socke ...

  3. Socket异步通信学习二

    接下来是服务器部分,采用异步模式,新建了一个AsynServer类,用于存放socket服务器代码,主要有4个方法: 有一个全局socket,下面四个方法中都用到. Socket socket = n ...

  4. Socket异步通信学习一

    最近在做一个频谱管理项目,负责通信模块,自己也是小白,重头学起,直至今天通信基本框架已经完成,把自己在学习中的心得与大家分享一下,做一个socket系列的博文,顺便加固一下自己对socket通信的认识 ...

  5. Socket异步通信及心跳包同时响应逻辑分析。

    有段时间没有更博了,刚好最近在做Socket通信的项目,原理大致内容:[二维码-(加logo)]-->提供主机地址和端口号信息(直接使用[ThoughtWorks.QRCode.dll]比较简单 ...

  6. Socket 异步通信

    最近在写数据通信的时候用到的东西!希望对大家有帮助 /// <summary> /// 获取或设置服务器IP地址 /// </summary> public string se ...

  7. Socket异步通信及心跳包同时响应逻辑分析(最后附Demo)。

    有段时间没有更博了,刚好最近在做Socket通信的项目,原理大致内容:[二维码-(加logo)]-->提供主机地址和端口号信息(直接使用[ThoughtWorks.QRCode.dll]比较简单 ...

  8. (转)C# Socket异步通信

    本文转载自:http://www.cnblogs.com/llllll/archive/2009/05/13/1455703.html 服务器端 TCPServer 1.使用的通讯通道:socket ...

  9. Socket 异步通信示例

    这个项目是一个控制台应用程序: 服务器端: using System; using System.Net; using System.Net.Sockets; using System.Text; u ...

随机推荐

  1. Java-集合框架总结

    集合框架: Java中的集合框架大类可分为Collection和Map:两者的区别: 1.Collection是单列集合:Map是双列集合 2.Collection中只有Set系列要求元素唯一:Map ...

  2. ViewModel从未如此清爽 - 轻量级WPF MVVM框架Stylet

    Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家. Stylet是受Caliburn Micro项目的启发, 所以借鉴 ...

  3. mysql revise

    DATABASE create database db_name; use db_name; alter database db_name; drop database db_name; show d ...

  4. Windows系统如何使用sqlmap

    使用方法:需要安装python,不能安装最新版本的python3.2.2只能安装2.6-3.0这些版本,包括2.6,3.0 这里,我提供一个Python的安装包.点击这里下载→ Python2.7 然 ...

  5. Mac下将ISO写入U盘镜像

    在Mac下面如果想做一个启动U盘,确实不如windows下那么方便,Windows下面有ultraiso+王涛,Mac下面测可以用下面的办法. 打开磁盘工具 插入U盘,并在磁盘工具里面找到U盘,把它卸 ...

  6. .NET和JAVA 反射对比

    反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等程序集内部的信息.使用反射可以看到一个程序集内部的接口.类.方法.字段.属性.特性等等信息.在System.Reflectio ...

  7. Ubuntu下Tomcat初始配置

    1.下载tomcat安装包 从tomcat官方网站http://tomcat.apache.org下载安装包,然后解压到某个目录,比如: ~/opt/apache-tomcat-7.0.63官方文档中 ...

  8. 14.Java中的Future模式

    jdk1.7.0_79  本文实际上是对上文<13.ThreadPoolExecutor线程池之submit方法>的一个延续或者一个补充.在上文中提到的submit方法里出现了Future ...

  9. An internal error occurred during: "Launching New_configuration"

    问题: 点击运行时eclipse报错如下: An internal error occurred during: "Launching New_configuration". Pa ...

  10. 在PHP中连接数据库的八大步骤

                                                                                   连接数据库的八大步骤  Step1:链接数 ...