Socket异步通信学习二
接下来是服务器部分,采用异步模式,新建了一个AsynServer类,用于存放socket服务器代码,主要有4个方法:
有一个全局socket,下面四个方法中都用到。
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
类框架如下:

1.构造方法public AsynServer(IPEndPoint endpoint,int listenMaxNum)
用于初始化socket服务器,IPEndPoint参数是socket绑定的终结点,listenMaxNum参数是监听队列的挂起的最大长度,代码如下:
public AsynServer(IPEndPoint endpoint,int listenMaxNum)
{
socket.Bind(endpoint); //绑定终结点
socket.Listen(listenMaxNum);//将socket至于侦听状态,设置挂起队列最大值为listenMaxNum
Console.WriteLine("正在连接客户端....");
AsynAccept(); //开始异步监听
// return socket;
}
2.异步监听方法public void AsynAccept()
public void AsynAccept()
{
socket.BeginAccept(asyncResult => {
socket = socket.EndAccept(asyncResult); //异步监听成功,返回socket
Console.WriteLine("客户端{0}异步连接成功", socket.RemoteEndPoint.ToString());
AsynReceive();
AsynSend("Server:Hello,client!");
}, null);
}
需注意的是异步socket的BeginAccept()方法必须以EndAccept()方法结束,EndAccept(asyncResult)通过回调BeginAccept中的asyncResult状态信息返回socket,这个socket是与客户端建立连接后的socket,需要把它赋给全局socket(后面的方法中会调用)。
另外,AsynAccept并不会阻塞主线程,因为系统会为BeginAccept()方法自动开一个线程,并阻塞该线程直到收到客户端连接,回调lamda表达式中的接收代码。
采用lamda变得式写的回调函数,不熟悉的同学请恶补一下吧,用起来很方便的:-)
连接成功了会收到客户端发来的信息,(AsynReceive()也是异步的,不会阻碍主线程),并给客户端发送问候信息,(AsynReceive()和AsynSend()都是异步的,不会阻碍主线程)。
3.异步接收方法private void AsynReceive()
private void AsynReceive()
{
byte[] data = new byte[];//接收缓存
string receiveStr;
socket.BeginReceive(data, , data.Length, SocketFlags.None, asyncResult => {
int length = socket.EndReceive(asyncResult);
if (length != )
{
receiveStr = Encoding.ASCII.GetString(data, , length);//获取缓存中的信息
Console.WriteLine(receiveStr); AsynReceive();//继续开新线程接收
}
else { Console.WriteLine("客户端{0}:关闭socket连接", socket.RemoteEndPoint.ToString());//socket.RemoteEndPoint.ToString()是客户端IP地址
socket.Close();
}
}, null); }
AsynReceive()
4.异步发送方法public void AsynSend()
public void AsynSend(string msg)
{
byte[] data = Encoding.UTF8.GetBytes(msg);
socket.BeginSend(data, , data.Length, SocketFlags.None, asyncResult =>
{
int length = socket.EndSend(asyncResult);
Console.WriteLine("message send to {0} successfully", socket.RemoteEndPoint.ToString());
}, null);
}
public void AsynSend(string msg)
因为socket收发都是采用字节流的形式,所以接收需要用byte[] data = new byte[1024],缓存收到的字节流,然后通过Encoding.ASCII.GetString(data, 0, length)方法把字节流转化为字符串输出;发送通过byte[] data = Encoding.UTF8.GetBytes(msg),把字符串信息转化为字节流发送。EndReceive(),EndSend()方法返回的都是收发字节数(int)
以上都是最简单的,只能实现基本的通信功能,后期会在此基础上完善,帮助初学者少走弯路,我当时可是学的头昏眼花-_-||
下篇是采用与服务器完全不同模式的客户端,同步模式
Socket异步通信学习二的更多相关文章
- Socket异步通信学习一
最近在做一个频谱管理项目,负责通信模块,自己也是小白,重头学起,直至今天通信基本框架已经完成,把自己在学习中的心得与大家分享一下,做一个socket系列的博文,顺便加固一下自己对socket通信的认识 ...
- Socket异步通信学习三
接下来是客户端部分,采用同步接收模式,在SocketClient项目中新建了一个SynServer类,用于存放socket服务器代码,和AsynServer类似,主要有4个方法: 有一个全局socke ...
- Linux学习之socket编程(二)
Linux学习之socket编程(二) 1.C/S模型——UDP UDP处理模型 由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...
- TCP协议和socket API 学习笔记
本文转载至 http://blog.chinaunix.net/uid-16979052-id-3350958.html 分类: 原文地址:TCP协议和socket API 学习笔记 作者:gilb ...
- C#高性能大容量SOCKET并发(二):SocketAsyncEventArgs封装
原文:C#高性能大容量SOCKET并发(二):SocketAsyncEventArgs封装 1.SocketAsyncEventArgs介绍 SocketAsyncEventArgs是微软提供的高性能 ...
- emberjs学习二(ember-data和localstorage_adapter)
emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...
- ReactJS入门学习二
ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...
- socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto
socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...
- TweenMax动画库学习(二)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
随机推荐
- Ext基础一(转载)
要学习及应用好Ext框架,必须需要理解Html DOM.Ext Element及Component三者之间的区别. 每一个HTML页面都有一个层次分明的DOM树模型,浏览器中的所有内容都有相应的DOM ...
- android利用WebView实现浏览器的封装
android提供了封装浏览器的接口,可以让开发者利用自己的view显示网页内容.今天又实现研究了一下,利用WebView显示浏览器内容,还可以利用 WebViewClient显示自己需要的内容. 参 ...
- Spring整合Hessian
Spring让Hessian变得不但强大,而且易用,但是易用背后,却有不少陷阱! 这个例子很简单,但实际上的确花费了我超过一小时的时间,排除了种种问题,最后问题终于水落石出. 整合以上篇Hel ...
- ccr test
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 11、四大组件之二-Service高级(二)Native Service
一.Service的分类 1.1>Android Service 使用Java编写在JVM中运行的服务 1.2>Native Service 使用C/C++完成的服务,一般在系统开始时完成 ...
- selenium IDE & Remote Control & Webdriver
一直忘记写selenium的开始学习的过程,今天趁五一,天气有雨,写下这文章 1.进入selnium官网,了解selenium1,2,grid的区别.下载c#相关的包(使用c#的人非常少) 2.使用I ...
- CenOS中下载RPM包
在实施部署时,往往服务器环境无外网或无法访问国外网址.这是可以在本机虚拟机的CentOS环境中下载RPM. 方法一:yum yum命令本身就可以用来下载一个RPM包,标准的yum命令提供了--down ...
- 【暑假】[深入动态规划]UVAlive 4794 Sharing Chocolate
UVAlive 4794 Sharing Chocolate 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12055 ...
- [C++]VS2010功能设置
VS2010快捷键设置 工具->选项->环境->键盘->[显示命令包含] 下面输入“对齐”关键字->窗口显示关于“对齐”的所有操作命令->选中“某一个”->[ ...
- Objective-C Runtime 运行时之五:协议与分类
Objective-C中的分类允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以做到. Objective-C中的协议是普遍存在的 ...