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 ...
随机推荐
- Win10 查看IE的临时目录
C:\Users\YOUR_NAME\AppData\Local\Microsoft\Windows\INetCache
- 如何使用spring中的Log4jConfigListener--删除
使用spring中的Log4jConfigListener有如如下好处: 1. 动态的改变记录级别和策略,不需要重启Web应用,如<Effective Enterprise Java> ...
- NGINX(一)内存结构
ngx_buf_t和ngx_chain_t是nginx中操作内存的重要手段, 很多的数据都需要通过这个结构进行保存. 其中ngx_buf_t中保存一块可用内存, ngx_chain_t则是将内存块连接 ...
- Js(Jquery)实现的弹出窗口
想实现一个弹出层,过一段时间自动消失的功能. 之前的项目中是:在页面中预先先一个<div>区域,默认隐藏或者因为没有内容不显示.当需要显示信息时,将该<div>填充上内容,并用 ...
- Code First 更新数据库结构
参考:http://blog.csdn.net/sxycxwb/article/details/12186159 0.删除之前的数据库 1.Run the Enable-Migrations comm ...
- HW6.8
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- 如何写出性能好的sql
开发人员是很少注意SQL对数据库性能影响的重要性的,大多程序员都会认为SQL是比较简单的,需要的时候查查手册就可以了,很少有深究的. 这样的观念对大型系统的开发是致命的,需要纠正这样的观念. 造成这样 ...
- CentOS6.5配置MySQL主从同步
原文地址:http://www.cnblogs.com/zhongshengzhen/ 修改主MySQL的配置 [root@localhost etc] vi /etc/my.cnf 添加以下配置 ...
- mysql服务的启动和停止 net stop mysql net start mysql
第一招.mysql服务的启动和停止 net stop mysql net start mysql 第二招.登陆mysql 语法如下: mysql -u用户名-p用户密码 键入命令mysql -uroo ...
- Select-Object用法
展开 modules 属性的详细信息 get-process |? {$_.processname -eq "cmd"}|select -ExpandProperty module ...