第一次使用Socket,遇到过坑,也涨过姿势,网上关于SuperSocket的教程基本都停留在官方给的简单demo上,实际使用还是会碰到一些问题,所以准备写两篇博客,分别来介绍SuperSocket以及实际的案例应用,应用中我还遇到一些问题,还没解决,还请有经验的指出问题

--------------------------------------------------------------------------------begin-------------------------------------------------------------------------------

先奉上官方网址:http://www.supersocket.net/  源码:http://supersocket.codeplex.com/releases/view/161987

官方的源码目前就不推荐看了,毕竟也是新手,不一定看得懂,使用前先看下官方的文档:http://docs.supersocket.net/  官方源码目录中有个QuickStart文件夹,顾名思义就是快速开始,官方的Demo,这里很想吐槽,网上的很多Demo都是官方Demo都是这个源码中最简单的那个,操,那有个毛用!这一篇就不扯其他的了,只讲SuperSocket的使用

本人书读的比较少,文笔比较差,所以我尽量来写清楚SuperSocket的使用逻辑

一个SuperSocket的程序,可以包含多个Socket服务(称为AppServer),一个Socket服务中有多个客户端连接对象(称这个连接对象为AppSession),一个客户端与Socket服务通讯命令都在AppSession中进行(称这个命令为Commands),每一个命令在被执行前我们可以来控制这个命令是否给予执行,类似与MVC中的 Action Filter(称为CommandFilterAttribute),还有一些其他的例如命令行协议的,用默认的就可以了,复杂的Socket程序可能需要自定义协议,这里我们不予深究(其实也简单,搞懂上面的,这个就好搞了)

接下来我拿我项目的代码分别对上面列出的概念来说明

我用的是最新的SuperSocket1.6.4.0,VS2013,需要使用三个官方提供的类库:SuperSocket.Common.dll,SuperSocket.SocketBase.dll,SuperSocket.SocketEngine.dll,上面忘了说了,SuperSocket集成了日志插件:log4net,所以这里我们也要引用,注意这个1.6.4.0对应的log4net版本为:1.2.13.0,一定要使用官方Demo包中的dll,避免版本引用不一致的问题,项目结构(控制台程序):

结构实际是参照官方的,如图:,对应文件夹为:

这是一个将Socket程序的宿主使用Windows服务的形式运行,为什么要使用WindowsService就不解释了,后面再会写篇来介绍使用服务。我曾建个普通的windows服务项目,把SuperSocket的代码集成进去,无奈服务启动就特么停止,不清楚为啥,所以使用官方提供的Demo,官方的代码我就不解释了(其实是我也没看懂...),我们要通过配置文件来启动Socket程序,所以先看下App.config

<configuration>
<configSections>
<section name="log4net" type="System.Configuration.IgnoreSectionHandler"/><!-- 注册log4net -->
<section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine"/><!-- 注册SuperSocket -->
</configSections>
<appSettings>
<add key="ServiceName" value="SupperSocketService"/> <!-- 服务名称 -->
<add key="ServiceDescription" value="试镜成Socket程序"/>  <!-- 服务说明 -->
</appSettings>
<superSocket>
<servers>
<server name="WeChatSocket" textEncoding="gb2312" serverType="LXGlass.SocketService.WeChatServer, LXGlass.SocketService" ip="Any" port="" maxConnectionNumber="">
</server> <!-- 一个socket服务(AppServer),当然可以配置多个 -->
</servers>
</superSocket>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
<runtime>
<gcServer enabled="true" />
</runtime>
</configuration>

上面说了,每个命令都在AppSession中,所以先来建个AppSession:

/// <summary>
/// 微信Session
/// </summary>
public class WeChatSession:AppSession<WeChatSession>
{ /// <summary>
/// 是否登录
/// </summary>
public bool isLogin { get; set; } /// <summary>
/// 机器编码
/// </summary>
public string SN { get; set; } protected override void OnSessionStarted()
{
//this.Send("Welcome to SuperSocket WeChat Server\r\n");
} protected override void OnInit()
{
//this.Charset = Encoding.GetEncoding("gb2312");
base.OnInit();
} protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
{
LogHelper.WriteLog("收到命令:" + requestInfo.Key.ToString());
this.Send("不知道如何处理 " + requestInfo.Key.ToString() +" 命令\r\n");
} /// <summary>
/// 异常捕捉
/// </summary>
/// <param name="e"></param>
protected override void HandleException(Exception e)
{
this.Send("\n\r异常信息:{0}", e.Message);
//base.HandleException(e);
} /// <summary>
/// 连接关闭
/// </summary>
/// <param name="reason"></param>
protected override void OnSessionClosed(CloseReason reason)
{
base.OnSessionClosed(reason); }
}

在这个Session中我额外定义了两个属性:isLogin、SN,Session也就类似与asp.net中的Session

接着把AppSession注册到服务(AppServer)中

/// <summary>
/// 微信服务
/// </summary>
//[WeChatCheckCommandFilter]
public class WeChatServer:AppServer<WeChatSession>
{ protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
{
return base.Setup(rootConfig, config);
} protected override void OnStarted()
{
LogHelper.WriteLog("WeChat服务启动");
base.OnStarted(); } protected override void OnStopped()
{
LogHelper.WriteLog("WeChat服务停止");
base.OnStopped();
} /// <summary>
/// 新的连接
/// </summary>
/// <param name="session"></param>
protected override void OnNewSessionConnected(WeChatSession session)
{
//LogHelper.WriteLog("WeChat服务新加入的连接:" + session.LocalEndPoint.Address.ToString());
base.OnNewSessionConnected(session);
} }

注意这两个类的继承关系,代码很简单,我把我的业务代码删掉了,先搞懂supersocket

再接着就是关键了(其实这些都是关键....),命令!先建一个CHECK的命令:

public class CHECK : CommandBase<WeChatSession, StringRequestInfo>
{
public override void ExecuteCommand(WeChatSession session, StringRequestInfo requestInfo)
{
if (requestInfo.Parameters.Count() != )
{
session.Send("The wrong format\r\n");
}
else
{
string sn = requestInfo.Parameters[].ToString();
if (string.IsNullOrWhiteSpace(sn))
session.Send("The wrong sn\r\n");
else
{
//已用此SN注册的连接会替换Sesion
var session_client = session.AppServer.GetAllSessions().Where(c => c.SN == sn);
if (session_client != null)
{
foreach (var item in session_client)
{
item.Send("new check,To close the connection for you\r\n");
item.Close();
}
} session.isLogin = true;
session.SN = sn;
session.Send("success\r\n");
}
}
}
}

这个命令继承自:CommandBase<WeChatSession, StringRequestInfo>,WeChatSession为我们刚才写的Session,StringRequestInfo为当前请求命令中的信息

当客户端发送:CHECK 1\r\n 就会收到success的返回,关于这个格式,就是命令行协议了,我这里使用默认的,想要自定义,去参照官方文档,这个默认的命令行协议的规则:每次请求和响应的数据结尾都有\r\n也就是换行符,通过\r\n来判断命令的结尾,CHECK为命令key,requestInfo.Key可以获得,上面的requestInfo.Parameters[0]是这个key后面以空格进行分割得到数组,所以requestInfo.Parameters[0]就可以取到CHECK 1 \r\n中的1,需要更多的数据就继续空格加

我代码中有段:已用此SN注册的连接会替换Sesion这里解释一下,因为每连上一个客户端,我们都要给他一个标识(这也是CHECK命令存在的意义),当一个客户端已用这个CHECK 1注册了,另外一个客户端也要用CHECK 1来注册,那程序就有两个sn=1的session了,为了保证唯一性,所以这里要把之前已注册CHECK=1的给踢掉,请无视item.send中的英文

需要其他命令的再添加类,继承CommandBase<WeChatSession, StringRequestInfo>

推荐个Socket客户端调试工具:SocketTool,下载地址:http://pan.baidu.com/s/1dDcZCfJ

基础就到这里了,下一篇说说实际的应用

我的第一个Socket程序-SuperSocket使用入门(一)的更多相关文章

  1. 我的第一个Socket程序-SuperSocket使用入门(三)

    本来博客都停了,不打算更了,但今天百度一个socket的问题时无意间发现第一篇的socket文章权重仅次于SuperSocket网站,顿时觉得自己6到不行,再写一篇,讨论下数据持久化的问题 去年搞那个 ...

  2. 我的第一个Socket程序-SuperSocket使用入门(二)

    操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操 辛辛苦苦写那么久的博客,最后手贱点了全屏富文本编辑器 ...

  3. (一)你的第一个Socket程序

    概述 本文通过一个最简单的Socket通信来对每一步做通俗易懂的讲解让你了解这些函数到底是干什么用的.下面的代码虽然是用Pyhton实现的,但是你要知道这些通信机制并不是Python所定义的,因为这些 ...

  4. Hello Socket - 第一个Socket程序

    1. 首先,要编写windows下socket程序,必须要加入Winsock支持 2. 服务端监听程序(Server.cpp) #include<winsock2.h> //包含头文件 # ...

  5. 今天在网上查看了一个socket程序,运行的时候一直报错,经过队友解决?

    1.首先是问题代码ip_port = ('192.168.12.2',8001)2.上边的代码本身没有问题,但是必须经过修改自己本机的局域网IP地址才能顺利链接请参考上一篇blog的地址,查看本机的i ...

  6. Glue4Net简单部署基于win服务的Socket程序

    smark 专注于高并发网络和大型网站架规划设计,提供.NET平台下高吞吐的网络通讯应用技术咨询和支持 Glue4Net简单部署基于win服务的Socket程序 在写一些服务应用的时候经常把要它部署到 ...

  7. GPU 编程入门到精通(三)之 第一个 GPU 程序

    博主因为工作其中的须要.開始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识,鉴于之前没有接触过 GPU 编程,因此在这里特地学习一下 GPU 上面的编程.有志同道合的小伙伴 ...

  8. 第一个socket服务端程序

    第一个socket服务端程序 #include <stdio.h> #include <stdlib.h> #include <string.h> #include ...

  9. SuperSocket快速入门(二):启动程序以及相关的配置

    如何快速启动第一个程序 既然是快速入门,所以,对于太深奥的知识点将不做讲解,会在后续的高级应用章节中,会对SS进行拆解.所有的实例90%都是来自SS的实例,外加本人的注释进行讲解. 一般应用而言,你只 ...

随机推荐

  1. pandas的Series

    pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False) 首先介绍一下基本的: d ...

  2. review40

    使用URL创建对象的应用程序称为客户端程序. URL对象调用InputStream openStream()方法可以返回一个输入流,该输入流指向URL对象所包含的资源. InetAddress类可以将 ...

  3. review21

    Class是java.lang包中的类,该类的实例可以帮助程序创建其他类的实例或者取得其他类的对象的内部信息. 参考代码如下所示: package pack07; import java.util.D ...

  4. 一个android好博客

    http://blog.csdn.net/eastmount http://lishuaishuai.iteye.com/ 二维码:http://www.cnblogs.com/liuan/categ ...

  5. 吐槽XE3中的BUG:无法调试32位的应用程序

    我想用的功能在XE5中有BUG, 无奈转移到XE3中测试,发现了XE3还有另外一个问题:无法DEBUG 32位的应用程序,这算什么事啊?有人说把项目属性中的link with dynamic RTL去 ...

  6. sql语句中as的用法和作用

    最近做项目中,偶然发现在SQL语句中出现了as这个词,一直以来没怎么关注是什么意思,毕竟影响不大,今天有空,就在网上查了一些资料,大概有了一些的了解 我们的Sql语句在很多数据库中都是通用的,比如像M ...

  7. 剑指offer--18.从尾到头打印链表

    递归,逐个加到后面 ------------------------------------------------------------------------------ 时间限制:1秒 空间限 ...

  8. canvas基础学习(一)

    一.概述 canvas它和其它的HTML5标签的使用基本一致,但是它相当于在浏览器中建立一个画布,可以再这个画布上画图.创建动画甚至是3D游戏.由于canvas要适配不同终端的分辨率,所以尽可能的在标 ...

  9. git教程4-创建分支与删除分支

    一.分支的理解 分支,即branch,用于从主分支(master)中新开辟出一个分支,用于对文件进行修改.这部分修改的内容在新的分支未融合到主分支的情况下,主分支是看不见的.新的分支相当于开辟了新的修 ...

  10. BZOJ- 2733: 永无乡 (并查集&线段树合并)

    题意:给定N个节点,K次操作,操作有两种,1是合并两个集合,2是求某个集合的第K大(从小到大排序). 思路:合并只要启发式即可.此题可以用线段树,保存1到N的排序的出现次数和. 复杂度O(NlogN) ...