FastSocket这个东西上次我已经说过,它使用简单,功能强大,扩展灵活,目前在新浪的生产环境中已经被广泛使用,所以它的性能,安全等各方面我们绝对可以信赖,今天我们来说一个话题,和上一讲有关,这次我们制作一个基于FastSocket的传输协议,它的意义重大,当fastSocket提供的协议不能满足项目要求时,我们就必须硬着头皮去自己写了,还好,fastsocket为我们铺好了路,我们只要按着这条路走下去,就可以了。

自定义的协议格式如下

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0YAAAAmCAIAAABvWhyIAAAFTklEQVR4nO2WSxbiOgxEWQoLf5vsGcMevRw6tsolJQGbXM6dxDj6lMugx+vPfwAAAACwNI+vVwAAAAAAB2GkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5WGkAwAAAFgeRjoAAACA5emPdM//P1+v71vo3i9VZhd8dxbfOpobtoywk8Ml/a7CM4AHfpXJpbuivNY//lvb5nCk66bJJltOUCf+u+h+hc+3j17sRo6SRhHMfrcXn/9+pm1Z1+nXljVD+8mqrbOkhBWKHfFSezrdaI5hapoXzmV+YcW2i3BKLaj9rQg65hIe2EU45XLVxL+V9/yCC1I7m1PBTVcPX2ekS2tqphbRtnvrZ3f+LY74QIf6pZazylyariDsy/53SQkb7RT/Op+X6zXyzITC3vxvFQ+InUcuV038W3mvkMVP6uxMBTddPXzdGulejVPfH9s7sFvRj7sgOrLuuRvEzNg+Ri92lTmleOcxKkbrIESOQomM87S8q0fYQNfZnn63F/EolBFJjwgrZDF1HkZohW0XRYQoZtvgULTuuYgX5xFWBBRS7DakpGsPqHtkkaTZoxEp8IAWod2fkjFbXuoEh0JFes7jvYJ62hjPfz/DU4661lJEsuh+t8eH6YNuOL9ikaUWxJfPtFfbdfe0utGGO4fFD1sWBZg66GhCz5lbbuvRQRxxagUf91tW2Nauu5t/RNhu/eLu11bmvKTnChvpXHayKZ0paeSB7NF09cEDwxTly+V8FZVxE+8V1DOrHbaQDV4+qfaVh+kDx3m64ihLLcgR+QqXUP9SDHduK5H5ar8U7zGHJtDRRAFTtZy9V13f6nai8kTNB8UvCGt2XRZWdBeJ9huX9HRho4BlJ/vSZc1v6uZfIjwwTFG+XM5XURk38Z6p3vsn26+uwQ9ePqn2lUfKB20bUdG7CO3jthgV3Y0sDqn7SuFssro7O7W8+oSyYX0ddNg5W478ZgZxxBG9RCpFCmgzHxTW6TolrEjRli0Mo1dMcxZqnlPYqAxTiqG1hlmym534w8rxgIjQ7ty9FflHy6iP4J7eG0pUa6096KGLzDhdbzj9bosPYYJu9GEbfj++fMPg12k63OPsjKpy9mRf8XXQYedsedjd8YuXWtyFTZn5oLBO12cJ69z92oop2icv6bnCRmVkXeerFLVvbs4mFZULKfTij3ngisvlfOUctLO4qPcK6mX7TRVWcHX2pF6pkc4vzuynu+JEdlZ8J33gl8J3Z6GAU1oWgs/ccvbgDv5M1LKf66VU176w3Szlu28GnOqSXids1NRQipRKYtH8pTV1S11tPGDq4JRqKjyMeRPvORIdd6OIf9zV2ZN6HRzptpp2lYnH4SsicuuVKI5WJMr4LnH0Yiu33ukI1ZVICB7pYC6+V/6+IgSfp+V2m69JTTGRKGrfjH+KsLqvlJfaIKLfqNMomqhTaNKtJCrvGRz3DMI6akdeMveLZoWkXdGGpzysBA90v4raMWWPFNYbbus9RyI/S7cFHX8YPDJMod9t8VF2yUV8PnU24wcqbFP49qXlD7fg3O0fFvYzICzgAZiTGc56PNLt5sqrq1kr46V17oK3E/pxoQqvr9vypb5qK7+PsFdz80sKLzwA0/P1I945rT/SAQAAAMBCMNIBAAAALA8jHQAAAMDyMNIBAAAALA8jHQAAAMDyMNIBAAAALA8jHQAAAMDyMNIBAAAALA8jHQAAAMDyMNIBAAAALM9fcDvieBUsHLMAAAAASUVORK5CYII=" alt="" />

说干就干

首先,如果要想扩展一个自己的协议,要对 client和server端分别进行开发,下面我们来看一下client的开发

aaarticlea/png;base64,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" alt="" />

我们要添加的类有三个文件组成,分别是DSSBinaryProtocol,DSSBinaryResponse和一个使用这个协议的客户端入口DSSBinarySocketClient

DSSBinaryProtocol

  /// <summary>
/// 异步二进制协议
/// 协议格式
/// [Message Length(int32)][SeqID(int32)][ProjectID(int16)][Cmd Length(int16)][VersonNumber Length(int16)][Cmd + VersonNumber + Body Buffer]
/// 其中参数TableName和VersonNumber长度为40,不够自动在左侧补空格
/// </summary>
public sealed class DSSBinaryProtocol : IProtocol<DSSBinaryResponse>
{ #region IProtocol Members
/// <summary>
/// find response
/// </summary>
/// <param name="connection"></param>
/// <param name="buffer"></param>
/// <param name="readlength"></param>
/// <returns></returns>
/// <exception cref="BadProtocolException">bad async binary protocl</exception>
public DSSBinaryResponse FindResponse(IConnection connection, ArraySegment<byte> buffer, out int readlength)
{
if (buffer.Count < ) { readlength = ; return null; } //获取message length
var messageLength = NetworkBitConverter.ToInt32(buffer.Array, buffer.Offset);
if (messageLength < ) throw new BadProtocolException("bad async binary protocl"); readlength = messageLength + ;
if (buffer.Count < readlength) { readlength = ; return null; } var seqID = NetworkBitConverter.ToInt32(buffer.Array, buffer.Offset + );
var projectID = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + );
var flagLength = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + );
var versonLength = NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + );
var strName = Encoding.UTF8.GetString(buffer.Array, buffer.Offset + , flagLength);
var versonNumber = Encoding.UTF8.GetString(buffer.Array, buffer.Offset + + flagLength, versonLength); var dataLength = messageLength - - flagLength - versonLength;
byte[] data = null;
if (dataLength > )
{
data = new byte[dataLength];
Buffer.BlockCopy(buffer.Array, buffer.Offset + + flagLength + versonLength, data, , dataLength);
}
return new DSSBinaryResponse(seqID, projectID, strName, versonNumber, data);
}
#endregion
}

DSSBinaryResponse

    /// <summary>
/// 数据同步系统DSS使用的Socket协议,我们称为DSSBinary协议
/// [Message Length(int32)][SeqID(int32)][ProjectID(int16)][Cmd Length(int16)][VersonNumber Length(int16)][Cmd + VersonNumber + Body Buffer]
/// </summary>
public class DSSBinaryResponse : IResponse
{
/// <summary>
/// 流水ID
/// </summary>
public int SeqID { get; private set; }
/// <summary>
/// 项目类型编号
/// </summary>
public short ProjectID { get; set; }
/// <summary>
/// 本次传输的版本号,所有客户端唯一[项目名称(4字节)+guid(36字节)]
/// </summary>
public string VersonNumber { get; private set; }
/// <summary>
/// 命令名称
/// </summary>
public string Flag { get; private set; } /// <summary>
/// 要操作的表对象,以字节数组形式进行传输
/// </summary>
public readonly byte[] Buffer = null; public DSSBinaryResponse(int seqID,
short projectID,
string flag,
string versonNumber,
byte[] buffer)
{
this.SeqID = seqID;
this.ProjectID = projectID;
this.VersonNumber = versonNumber;
this.Flag = flag;
this.Buffer = buffer;
}
}

DSSBinarySocketClient

   /// <summary>
/// 异步socket客户端
/// </summary>
public class DSSBinarySocketClient : PooledSocketClient<DSSBinaryResponse>
{
#region Constructors
/// <summary>
/// new
/// </summary>
public DSSBinarySocketClient()
: base(new DSSBinaryProtocol())
{
}
/// <summary>
/// new
/// </summary>
/// <param name="socketBufferSize"></param>
/// <param name="messageBufferSize"></param>
public DSSBinarySocketClient(int socketBufferSize, int messageBufferSize)
: base(new DSSBinaryProtocol(), socketBufferSize, messageBufferSize, , )
{
}
/// <summary>
/// new
/// </summary>
/// <param name="socketBufferSize"></param>
/// <param name="messageBufferSize"></param>
/// <param name="millisecondsSendTimeout"></param>
/// <param name="millisecondsReceiveTimeout"></param>
public DSSBinarySocketClient(int socketBufferSize,
int messageBufferSize,
int millisecondsSendTimeout,
int millisecondsReceiveTimeout)
: base(new DSSBinaryProtocol(),
socketBufferSize,
messageBufferSize,
millisecondsSendTimeout,
millisecondsReceiveTimeout)
{
}
#endregion #region Public Methods public Task<TResult> Send<TResult>(string cmdName, short projectID, string versonNumber, byte[] payload,
Func<DSSBinaryResponse, TResult> funcResultFactory, object asyncState = null)
{
return this.Send(null, cmdName, projectID, versonNumber, payload, funcResultFactory, asyncState);
} public Task<TResult> Send<TResult>(byte[] consistentKey, string cmdName, short projectID, string versonNumber, byte[] payload,
Func<DSSBinaryResponse, TResult> funcResultFactory, object asyncState = null)
{
if (string.IsNullOrEmpty(cmdName)) throw new ArgumentNullException("cmdName");
if (funcResultFactory == null) throw new ArgumentNullException("funcResultFactory"); var seqID = base.NextRequestSeqID();
var cmdLength = cmdName.Length;
var versonNumberLength = versonNumber.Length;
var messageLength = (payload == null ? : payload.Length) + cmdLength + versonNumberLength + ;
var sendBuffer = new byte[messageLength + ]; //write message length
Buffer.BlockCopy(NetworkBitConverter.GetBytes(messageLength), , sendBuffer, , );
//write seqID.
Buffer.BlockCopy(NetworkBitConverter.GetBytes(seqID), , sendBuffer, , );
//write proejctID
Buffer.BlockCopy(NetworkBitConverter.GetBytes(projectID), , sendBuffer, , );
//write response flag length.
Buffer.BlockCopy(NetworkBitConverter.GetBytes((short)cmdLength), , sendBuffer, , );
//write verson length
Buffer.BlockCopy(NetworkBitConverter.GetBytes((short)versonNumberLength), , sendBuffer, , );
//write response cmd
Buffer.BlockCopy(Encoding.ASCII.GetBytes(cmdName), , sendBuffer, , cmdLength);
//write response versonNumber
Buffer.BlockCopy(Encoding.ASCII.GetBytes(versonNumber), , sendBuffer, + cmdLength, versonNumberLength);
//write body buffer
if (payload != null && payload.Length > )
Buffer.BlockCopy(payload, , sendBuffer, + cmdLength + versonNumberLength, payload.Length); var source = new TaskCompletionSource<TResult>(asyncState);
base.Send(new Request<DSSBinaryResponse>(consistentKey, seqID, cmdName, sendBuffer,
ex => source.TrySetException(ex),
response =>
{
TResult result;
try { result = funcResultFactory(response); }
catch (Exception ex) { source.TrySetException(ex); return; } source.TrySetResult(result);
}));
return source.Task;
}
#endregion
}

然后,我们再来说一下server端的开发,它有两个文件组成,分别是DSSBinaryCommandInfo,DSSBinaryProtocol

aaarticlea/png;base64,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" alt="" />

DSSBinaryCommandInfo

    /// <summary>
/// async binary command info.
/// </summary>
public class DSSBinaryCommandInfo : ICommandInfo
{
#region Constructors
/// <summary>
/// new
/// </summary>
/// <param name="cmdName"></param>
/// <param name="seqID"></param>
/// <param name="buffer"></param>
/// <exception cref="ArgumentNullException">cmdName is null or empty.</exception>
public DSSBinaryCommandInfo(int seqID, short projectID, string cmdName, string versonNumber, byte[] buffer)
{
if (string.IsNullOrEmpty(cmdName)) throw new ArgumentNullException("cmdName");
if (string.IsNullOrEmpty(versonNumber)) throw new ArgumentNullException("versonNumber"); this.VersonNumber = versonNumber;
this.CmdName = cmdName;
this.SeqID = seqID;
this.ProjectID = projectID;
this.Buffer = buffer;
}
#endregion #region Public Properties
/// <summary>
/// 版本号
/// </summary>
public string VersonNumber
{
get;
private set;
}
public short ProjectID { get; private set; }
/// <summary>
/// get the current command name.
/// </summary>
public string CmdName
{
get;
private set;
}
/// <summary>
/// seq id.
/// </summary>
public int SeqID
{
get;
private set;
}
/// <summary>
/// 主体内容
/// </summary>
public byte[] Buffer
{
get;
private set;
}
#endregion #region Public Methods
/// <summary>
/// reply
/// </summary>
/// <param name="connection"></param>
/// <param name="payload"></param>
public void Reply(IConnection connection, byte[] payload)
{
var packet = PacketBuilder.ToDSSBinary(this.SeqID, this.ProjectID, this.CmdName, this.VersonNumber, payload);
connection.BeginSend(packet);
}
#endregion }

DSSBinaryProtocol

    /// <summary>
/// 数据中心二进制协议
/// 协议格式
/// [Message Length(int32)][SeqID(int32)][Request|Response Flag Length(int16)][VersonNumber Length(int16)][Request|Response Flag + VersonNumber + Body Buffer]
/// </summary>
public sealed class DSSBinaryProtocol : IProtocol<DSSBinaryCommandInfo>
{
#region IProtocol Members
/// <summary>
/// find command
/// </summary>
/// <param name="connection"></param>
/// <param name="buffer"></param>
/// <param name="maxMessageSize"></param>
/// <param name="readlength"></param>
/// <returns></returns>
/// <exception cref="BadProtocolException">bad async binary protocl</exception>
public DSSBinaryCommandInfo FindCommandInfo(IConnection connection, ArraySegment<byte> buffer,
int maxMessageSize, out int readlength)
{
if (buffer.Count < ) { readlength = ; return null; } var payload = buffer.Array; //获取message length
var messageLength = NetworkBitConverter.ToInt32(payload, buffer.Offset);
if (messageLength < ) throw new BadProtocolException("bad async binary protocl");
if (messageLength > maxMessageSize) throw new BadProtocolException("message is too long"); readlength = messageLength + ;
if (buffer.Count < readlength)
{
readlength = ; return null;
} var seqID = NetworkBitConverter.ToInt32(payload, buffer.Offset + );
var projectID = NetworkBitConverter.ToInt16(payload, buffer.Offset + );
var cmdNameLength = NetworkBitConverter.ToInt16(payload, buffer.Offset + );
var versonNumberLength = NetworkBitConverter.ToInt16(payload, buffer.Offset + );
var strName = Encoding.UTF8.GetString(payload, buffer.Offset + , cmdNameLength);
var versonNumber = Encoding.UTF8.GetString(payload, buffer.Offset + + cmdNameLength, versonNumberLength); var dataLength = messageLength - - cmdNameLength;
byte[] data = null;
if (dataLength > )
{
data = new byte[dataLength];
Buffer.BlockCopy(payload, buffer.Offset + + cmdNameLength + versonNumberLength, data, , dataLength);
}
return new DSSBinaryCommandInfo(seqID, projectID, strName, versonNumber, data);
}
#endregion
}

除了上面两个文件外,我们还要修改服务端的管理类

    /// <summary>
/// Socket server manager.
/// </summary>
public class SocketServerManager
{
#region Private Members
static private readonly List<SocketBase.IHost> _listHosts = new List<SocketBase.IHost>();
#endregion #region Static Methods
/// <summary>
/// 初始化Socket Server
/// </summary>
static public void Init()
{
Init("socketServer");
}
/// <summary>
/// 初始化Socket Server
/// </summary>
/// <param name="sectionName"></param>
static public void Init(string sectionName)
{
if (string.IsNullOrEmpty(sectionName)) throw new ArgumentNullException("sectionName");
Init(ConfigurationManager.GetSection(sectionName) as Config.SocketServerConfig);
}
/// <summary>
/// 初始化Socket Server
/// </summary>
/// <param name="config"></param>
static public void Init(Config.SocketServerConfig config)
{
if (config == null) throw new ArgumentNullException("config");
if (config.Servers == null) return; foreach (Config.Server serverConfig in config.Servers)
{
//inti protocol
var objProtocol = GetProtocol(serverConfig.Protocol);
if (objProtocol == null) throw new InvalidOperationException("protocol"); //init custom service
var tService = Type.GetType(serverConfig.ServiceType, false);
if (tService == null) throw new InvalidOperationException("serviceType"); var serviceFace = tService.GetInterface(typeof(ISocketService<>).Name);
if (serviceFace == null) throw new InvalidOperationException("serviceType"); var objService = Activator.CreateInstance(tService);
if (objService == null) throw new InvalidOperationException("serviceType"); //init host.
var host = Activator.CreateInstance(typeof(SocketServer<>).MakeGenericType(
serviceFace.GetGenericArguments()),
objService,
objProtocol,
serverConfig.SocketBufferSize,
serverConfig.MessageBufferSize,
serverConfig.MaxMessageSize,
serverConfig.MaxConnections) as BaseSocketServer; host.AddListener(serverConfig.Name, new IPEndPoint(IPAddress.Any, serverConfig.Port)); _listHosts.Add(host);
}
}
/// <summary>
/// get protocol.
/// </summary>
/// <param name="protocol"></param>
/// <returns></returns>
static public object GetProtocol(string protocol)
{
switch (protocol)
{
case Protocol.ProtocolNames.AsyncBinary:
return new Protocol.AsyncBinaryProtocol();
case Protocol.ProtocolNames.Thrift:
return new Protocol.ThriftProtocol();
case Protocol.ProtocolNames.CommandLine:
return new Protocol.CommandLineProtocol();
case Protocol.ProtocolNames.DSSBinary:
return new Protocol.DSSBinaryProtocol();
}
return Activator.CreateInstance(Type.GetType(protocol, false));
} /// <summary>
/// 启动服务
/// </summary>
static public void Start()
{
foreach (var server in _listHosts) server.Start();
}
/// <summary>
/// 停止服务
/// </summary>
static public void Stop()
{
foreach (var server in _listHosts) server.Stop();
}
#endregion
}

从上面的代码中,我们看到了自己新加的协议DSSBinary,我们可以在配置文件中对它进行配置,方法和之前说的一样,在这里就不再重复了。

感谢各位的阅读!

FastSocket学习笔记~制定自已的传输协议~续~制定基于FastSocket的协议的更多相关文章

  1. [原创]java WEB学习笔记49:文件上传基础,基于表单的文件上传,使用fileuoload 组件

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  2. mybatis学习笔记(二)-- 使用mybatisUtil工具类体验基于xml和注解实现

    项目结构  基础入门可参考:mybatis学习笔记(一)-- 简单入门(附测试Demo详细过程) 开始体验 1.新建项目,新建类MybatisUtil.java,路径:src/util/Mybatis ...

  3. .NET CORE学习笔记系列(2)——依赖注入【2】基于IoC的设计模式

    原文:https://www.cnblogs.com/artech/p/net-core-di-02.html 正如我们在<控制反转>提到过的,很多人将IoC理解为一种“面向对象的设计模式 ...

  4. FastSocket学习笔记~制定自已的传输协议

    对于TCP或者UDP来说,它们作于传输层的协议,有着自己的标准,或者叫格式,在我们看TCP格式之前先了解一下计算机的基础知识,字节,它是计算机世界的一个小单位,也是我们可以理会到的,如一个utf-8英 ...

  5. FastSocket学习笔记~再说客户端与服务端的组成

    废话多说 很久之前,我写过几篇FastSocket的文章,基本属于使用的方法,而缺乏对概念的总结讲解,而本讲就是弥补一下上几讲的不足,将核心的模块再说说,再谈谈,再聊聊! 首先FastSocket由C ...

  6. FastSocket学习笔记~RPC的思想,面向对象的灵活

    首先非常感谢这位来自新浪的老兄,它开发的这个FastSocket非常不错,先不说性能如何,单说它的使用方式和理念上就很让人赞口,从宏观上看,它更像是一种远程过程的调用RPC,即服务器公开一些命令,供客 ...

  7. Java学习笔记——Socket实现文件传输

    我越是逃离,却越是靠近你. 我越是背过脸,却越是看见你. 我从你开始, 我在你结束. 需求:实现局域网下socket传输文件. 客户端步骤: 1.建立与服务器的连接 2.创建client输出流 3.创 ...

  8. PMP项目管理学习笔记(5)——整合管理之制定项目章程

    关于两个输入 在很多过程中,会用到这两个输入: 企业环境要素 是关于你的公司如何开展业务所需要知道的所有信息. 在你计划项目时,有很多关于公司的信息会非常有用,你需要知道各个不同部门是如何运作的,你所 ...

  9. Python学习笔记八:文件操作(续),文件编码与解码,函数,递归,函数式编程介绍,高阶函数

    文件操作(续) 获得文件句柄位置,f.tell(),从0开始,按字符数计数 f.read(5),读取5个字符 返回文件句柄到某位置,f.seek(0) 文件在编辑过程中改变编码,f.detech() ...

随机推荐

  1. 基于私钥加密公钥解密的RSA算法C#实现

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...

  2. Linux/RedHat 编译安装GNU gcc 4.9.0 (g++)

    这里说的是编译安装,yum/apt-get 等安装方法比較简单,不阐述! 1.下载源代码包:gcc.gnu.org 2.解压: tar -xjvf gcc-4.9.0.tar.bz2 3.下载编译所需 ...

  3. 琐碎-关于Windows调试hadoop

    http://www.aboutyun.com/thread-7784-1-1.html 今天早上看了这个文章后我有点疑问,所以特地实践了一把. 之前也遇到了调试的时候 org.apache.hado ...

  4. iOS runtime 运行时( - )

    谈到运行时,相对应的就有编译时: 1).运行时-- 直到程序运行时才去确定一个对象的具体信息,并且可以改变这个类的具体信息,包括它的方法,变量等等: 2).编译时-- 是在程序运行之前,编译的时候,就 ...

  5. CSS 之 内层div填充margin,外层div的背景色不会覆盖该margin

    外层元素(如div)中只有一个非空子元素,此时margin是被折叠了.两者之间取最大的margin值,表现在外层父元素上,而不是内层子元素. 注意: (1)只有垂直方向上才会出现此现象,水平方向不会出 ...

  6. 如何删除Weblogic域

    1. delete entry in WL_HOME/common/nodemanager/nodemanager.domains 2. delete entry in FMW_HOME/domain ...

  7. Cows

    Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can ...

  8. cigarettes

    描述 Tom has many cigarettes. We hypothesized that he has n cigarettes and smokes them one by one keep ...

  9. 共享锁(S锁)和排它锁(X锁)

    1 什么叫数据库共享锁[S]锁和[X]锁 共享锁[S锁]    又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁.这保 ...

  10. ProcMon启用调试符

    1.设置 _NT_SYMBOL_PATH 如果在 _NT_SYMBOL_PATH 环境变量中提供了正确的?symsrv?语法,则常见的 Mircoroft 调试工具将使用 SymSrv 技术.这些工具 ...