.net DataExcel通信组件使用 搭建简单文件服务器
时间:2014-05-07 08:11:20
收藏:0
阅读:494
.net DataExcel通信组件使用 搭建简单文件服务器
使用.net dataexcel通信搭建一个简单的文件服务器。
通信简单介绍
1,通信使用TCP协议。
2,采用session机制,控制简单通信安全与连接限制防攻击。
3,采用开放协议包格。(32字节数据包)
4,采用网络断开,自动连接机制保证连接。
5,采用压缩机械压缩大数据(比如.net 里面datatable,dataset的传输)。
6,采用事件机制,更容易,更符合.net开发习惯。
7,采用异步传输,较大的连接与并发。
8,采用数据包头,解决粘包。
9,采用命令方式,更容易扩展。
10,采用允许事件加密,解密保证通信数据绝对安全。(只针对通信)。
11,允许可扩展通信,保证程序各版通信的版本管理。
12,采用无符号以及UNICODE编码,保证各平台的兼容性。(此通信的java版本)
主要类及使用方法介绍:
服务器端
服务器端 使用 SocketListener 类进行监听。
SocketListener listener = new SocketListener();
private void btnStart_Click(object sender, EventArgs e)
{
//this.listener.DbHelper.ConnectionString = frm.txtdatabase.Text;
listener.Port = int.Parse(this.txtport.Text); //这个是必须的,设置监听的端口
//listener.BeforeDataReceive += new SocketListener.BeforeDataReceiveEventHandler(listener_BeforeDataReceive);
listener.DataReceive += new SocketListener.DataReceiveEventHandler(server_DataReceive); //这个是必须的,用于接收自定义的命令。
//listener.ClientChanged += new ClientChangedHandler(listener_ClientChanged);
listener.RegeditSession += new Feng.Net.Tcp.SocketListener.RegeditSessionEventHandler(listener_RegeditSession); //这个是必须的,注册Session事件,指定连接是被允许。
//listener.Loged += new SocketListener.LogEventHandler(listener_Loged);
//listener.Connectioned += new SocketListener.ConnectedEventHandler(listener_Connectioned);
//listener.VersionChecked += new SocketListener.VersionCheckedEventHandler(listener_VersionChecked);
listener.Path = this.txtpath.Text; //这个不是必须的,设置服务器文件路径,用于做文件服务根目录。
listener.StartListening(); //这个是必须的,开启监听。
}
void listener_RegeditSession(object sender, RegeditSessionEventArgs e)
{
if (e.Password == "1001" && e.User == "1001") //可以在这里用数据库对比。
{
e.Session = new Random(DateTime.Now.Millisecond).Next(100, short.MaxValue - 10); //返回随意一个Session。
return;
}
}
{
//this.listener.DbHelper.ConnectionString = frm.txtdatabase.Text;
listener.Port = int.Parse(this.txtport.Text); //这个是必须的,设置监听的端口
//listener.BeforeDataReceive += new SocketListener.BeforeDataReceiveEventHandler(listener_BeforeDataReceive);
listener.DataReceive += new SocketListener.DataReceiveEventHandler(server_DataReceive); //这个是必须的,用于接收自定义的命令。
//listener.ClientChanged += new ClientChangedHandler(listener_ClientChanged);
listener.RegeditSession += new Feng.Net.Tcp.SocketListener.RegeditSessionEventHandler(listener_RegeditSession); //这个是必须的,注册Session事件,指定连接是被允许。
//listener.Loged += new SocketListener.LogEventHandler(listener_Loged);
//listener.Connectioned += new SocketListener.ConnectedEventHandler(listener_Connectioned);
//listener.VersionChecked += new SocketListener.VersionCheckedEventHandler(listener_VersionChecked);
listener.Path = this.txtpath.Text; //这个不是必须的,设置服务器文件路径,用于做文件服务根目录。
listener.StartListening(); //这个是必须的,开启监听。
}
void listener_RegeditSession(object sender, RegeditSessionEventArgs e)
{
if (e.Password == "1001" && e.User == "1001") //可以在这里用数据库对比。
{
e.Session = new Random(DateTime.Now.Millisecond).Next(100, short.MaxValue - 10); //返回随意一个Session。
return;
}
}
客户端
客户端 使用SocketClient类
private static SocketClient _client = null;
public static SocketClient Client
{
get
{
if (_client == null)
{
_client = new SocketClient();
_client.Port = Port; //这个是必须的设置远程服务监听的端口。
//_client.Host = "yufb12.eicp.net";//花生壳
_client.IPAdress = System.Net.IPAddress.Parse(IP); //这个是必须的设置远程服务器的IP。
_client.StartClient();
}
return _client;
}
}
public static SocketClient Client
{
get
{
if (_client == null)
{
_client = new SocketClient();
_client.Port = Port; //这个是必须的设置远程服务监听的端口。
//_client.Host = "yufb12.eicp.net";//花生壳
_client.IPAdress = System.Net.IPAddress.Parse(IP); //这个是必须的设置远程服务器的IP。
_client.StartClient();
}
return _client;
}
}
注意:如果这样使用,因为是属性,所以第一次调连接可能没有完成,所以你需要提示调用一次这个静态属性。
WINFORM窗口类注册客户端的连接事件。在连接事件注册Session。
client.Connected += new SocketClient.ConnectedEventHandler(client_Connected); //这里是必须的。
void client_Connected(object sender, SocketClient sh) //这里是必须的。
{
sh.RegeditSession("1001", "1001"); //用户名与密码,配合服务器数据库使用。保证连接是有效且被允许的。
}
{
sh.RegeditSession("1001", "1001"); //用户名与密码,配合服务器数据库使用。保证连接是有效且被允许的。
}
文件服务器所使用的内置函数
string[] paths = client.GetPaths(path); //返回服务器路径中的所有文件夹。
string[] files = client.GetFiles(path); //返回服务器路径中的所有文件。
TcpFileInfo fti = client.GetFileInfo(file); //返回服务器路文件的文件属性。
byte[] data = client.DownFile(path); //下载服务器路文件数据流。
client.SendFileToServer(path, dlg.FileName); //上传文件到服务器目录。
下面是自定义命令示例:
客户端发送自定包示例:
public const int YOURPROJECTNAME= 0x0251;
public const int YOURPROJECTNAME _SQLITEQUERY0 = 0x0234;
public const int YOURPROJECTNAME _SQLITEQUERY0 = 0x0234;
private void QuerySqlite(string sql)
{
Feng.Net.PacketHelper ph = new Feng.Net.PacketHelper();
ph.PacketMainCommand = YOURPROJECTNAME;
ph.PacketSubcommand = YOURPROJECTNAME_SQLITEQUERY0 ;
using (Feng.IO.BufferWriter bw = new Feng.IO.BufferWriter())
{
bw.Write(sql);
{
Feng.Net.PacketHelper ph = new Feng.Net.PacketHelper();
ph.PacketMainCommand = YOURPROJECTNAME;
ph.PacketSubcommand = YOURPROJECTNAME_SQLITEQUERY0 ;
using (Feng.IO.BufferWriter bw = new Feng.IO.BufferWriter())
{
bw.Write(sql);
bw.Write(new byte[]{});
ph.PacketContents = bw.GetData();
}
byte [] data=new byte [0];
if (client.Send(ph, out data))
{
ph = Feng.Net.PacketHelper.Get(data);
using (Feng.IO.BufferReader reader = new Feng.IO.BufferReader(ph.PacketContents))
{
DataTable table = reader.ReadDataTable();
}
}
}
ph.PacketContents = bw.GetData();
}
byte [] data=new byte [0];
if (client.Send(ph, out data))
{
ph = Feng.Net.PacketHelper.Get(data);
using (Feng.IO.BufferReader reader = new Feng.IO.BufferReader(ph.PacketContents))
{
DataTable table = reader.ReadDataTable();
}
}
}
类PacketHelper 为开放数据包。
ph.PacketMainCommand = YOURPROJECTNAME; //PacketMainCommand 为主命令,一般为你的项目名称。
ph.PacketSubcommand = SQLITEQUERY; //SQLITEQUERY 为子命令,定义具体函数操作。
BufferWriter 类 为转化为二进制数据流。
bw.Write(sql); //write有40多个函数的重载。此处为要送的SQL语句。
bw.Write(new byte[]{}); //此处保证数据向下个版本的兼容性。
ph.PacketContents = bw.GetData(); //PacketContents 这里为要发送的内容。bw.GetData()获取二进制数组。
if (client.Send(ph, out data)) //这里为阻塞发送,将阻塞当前线程。符合windows开发人员的习惯。超过超时时间返回FALSE.
ph = Feng.Net.PacketHelper.Get(data); //通过返回二制流,反回数据包。 PacketHelper.Get 这个静态函数为得到一个实例。
BufferReader 类 为从二进制转化某类对象
DataTable table = reader.ReadDataTable(); //读取返回的DataTable对象。
服务器端示例:
public const int SQLITEQUERY = 0x0251;
public const int YOURPROJECTNAME = 0x0234;
void server_DataReceive(object sender, ReciveEventArgs e, PacketHelper ph)
{
if (ph.PacketMainCommand == YOURPROJECTNAME)
{
switch (ph.PacketSubcommand)
{
case SQLITEQUERY:
using (Feng.IO.BufferReader reader = new Feng.IO.BufferReader(ph.PacketContents))
{
string sql = reader.ReadString();
DataTable dt = Query(sql);
using (Feng.IO.BufferWriter bw = new Feng.IO.BufferWriter())
{
bw.Write(dt);
ph.PacketContents = bw.GetData();
e.SocketHelper.Send(ph);
}
}
break;
default:
break;
}
}
}
public const int SQLITEQUERY = 0x0251;
public const int YOURPROJECTNAME = 0x0234;
void server_DataReceive(object sender, ReciveEventArgs e, PacketHelper ph)
{
if (ph.PacketMainCommand == YOURPROJECTNAME)
{
switch (ph.PacketSubcommand)
{
case SQLITEQUERY:
using (Feng.IO.BufferReader reader = new Feng.IO.BufferReader(ph.PacketContents))
{
string sql = reader.ReadString();
DataTable dt = Query(sql);
using (Feng.IO.BufferWriter bw = new Feng.IO.BufferWriter())
{
bw.Write(dt);
ph.PacketContents = bw.GetData();
e.SocketHelper.Send(ph);
}
}
break;
default:
break;
}
}
}
if (ph.PacketMainCommand == YOURPROJECTNAME) //判断主命令
switch (ph.PacketSubcommand) //确定执行的子命令
string sql = reader.ReadString(); //读取参数 这里发送的SQL语句。
DataTable dt = Query(sql); //调用函数 获取datatable.
bw.Write(dt); //写数据流 把查询的datatable发送出云。
e.SocketHelper.Send(ph); //直接发送当前数据包。
SOCKETCLIENT预置的函数:
Feng.Net.Tcp.SocketClient.Application_ApplicationExit(object, System.EventArgs) Feng.Net.Tcp.SocketClient.BeginPost(Feng.Net.PacketHelper, System.AsyncCallback) Feng.Net.Tcp.SocketClient.BeginPost(Feng.Net.PacketHelper, System.AsyncCallback,
object) Feng.Net.Tcp.SocketClient.Close() Feng.Net.Tcp.SocketClient.ConnectCallback(System.IAsyncResult) Feng.Net.Tcp.SocketClient.CreateServerPath(string) Feng.Net.Tcp.SocketClient.DeleteServerFile(string) Feng.Net.Tcp.SocketClient.DeleteServerPath(string)
Feng.Net.Tcp.SocketClient.DoCallBack(Feng.Net.Tcp.AsyncResultPost) Feng.Net.Tcp.SocketClient.DoChanged(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.DoRecvFile(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.DoRecvText(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.DownFile(string)
Feng.Net.Tcp.SocketClient.DownLoadFileFromServer(string, string) Feng.Net.Tcp.SocketClient.EndPost(System.IAsyncResult) Feng.Net.Tcp.SocketClient.GetFileInfo(string) Feng.Net.Tcp.SocketClient.GetFiles(string) Feng.Net.Tcp.SocketClient.GetOnlineUser() Feng.Net.Tcp.SocketClient.GetPaths(string)
Feng.Net.Tcp.SocketClient.GetReceiveData(byte[]) Feng.Net.Tcp.SocketClient.GetSendData(byte[]) Feng.Net.Tcp.SocketClient.OnClientChanged(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.OnClose(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.OnDataReceive(Feng.Net.ReciveClientEventArgs)
Feng.Net.Tcp.SocketClient.OnDownLoadFile(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.OnGetReceiveData(object) Feng.Net.Tcp.SocketClient.OnLineChecked(out int, byte[]) Feng.Net.Tcp.SocketClient.OnOtherLogin(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.OnRecviceUserData(Feng.Net.PacketHelper)
Feng.Net.Tcp.SocketClient.OnSessionChanged(int) Feng.Net.Tcp.SocketClient.OnSystemMessageRecv(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.OnToAllUser(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.OnToOtherUser(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.Post(Feng.Net.PacketHelper)
Feng.Net.Tcp.SocketClient.PostCallBack(object) Feng.Net.Tcp.SocketClient.Read() Feng.Net.Tcp.SocketClient.ReceiveCallback(System.IAsyncResult) Feng.Net.Tcp.SocketClient.RegeditSession(string, string) Feng.Net.Tcp.SocketClient.RegeditSession(string, string,
byte[]) Feng.Net.Tcp.SocketClient.Send(string) Feng.Net.Tcp.SocketClient.Send(Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.Send(Feng.Net.PacketHelper, out byte[]) Feng.Net.Tcp.SocketClient.Send(int, byte[], out byte[]) Feng.Net.Tcp.SocketClient.SendAndWaitingValue(Feng.Net.PacketHelper,
out byte[]) Feng.Net.Tcp.SocketClient.SendCallback(System.IAsyncResult) Feng.Net.Tcp.SocketClient.SendClosed() Feng.Net.Tcp.SocketClient.SendFileToOtherUser(string, string) Feng.Net.Tcp.SocketClient.SendFileToOtherUser(System.Collections.Generic.List<string>,
string) Feng.Net.Tcp.SocketClient.SendFileToServer(string, string) Feng.Net.Tcp.SocketClient.SendToAllClientFile(string) Feng.Net.Tcp.SocketClient.SendToAllUser(string) Feng.Net.Tcp.SocketClient.SendToAllUser(byte[]) Feng.Net.Tcp.SocketClient.SendToAllUser(Feng.Net.PacketHelper)
Feng.Net.Tcp.SocketClient.SendToOtherUser(string, string) Feng.Net.Tcp.SocketClient.SendToOtherUser(string, byte[]) Feng.Net.Tcp.SocketClient.SendToOtherUser(System.Collections.Generic.List<string>, string) Feng.Net.Tcp.SocketClient.SendToOtherUser(System.Collections.Generic.List<string>,
byte[]) Feng.Net.Tcp.SocketClient.SendToOtherUser(System.Collections.Generic.List<string>, Feng.Net.PacketHelper) Feng.Net.Tcp.SocketClient.SocketClient(System.Net.IPAddress, int) Feng.Net.Tcp.SocketClient.SocketClient() Feng.Net.Tcp.SocketClient.SocketClient(System.Net.IPAddress)
Feng.Net.Tcp.SocketClient.SocketClient(string) Feng.Net.Tcp.SocketClient.StartClient() Feng.Net.Tcp.SocketClient.StartConnection() Feng.Net.Tcp.SocketClient.ToString() Feng.Net.Tcp.SocketClient.UpdateChecked(out int, byte[]) Feng.Net.Tcp.SocketClient.VersionChecked(string,
int, out int, out string, byte[]) Feng.Net.Tcp.SocketClient.AutoConnected Feng.Net.Tcp.SocketClient.DefaultWaitConnectionTime Feng.Net.Tcp.SocketClient.FileTempPath Feng.Net.Tcp.SocketClient.HasConnected Feng.Net.Tcp.SocketClient.Host Feng.Net.Tcp.SocketClient.Index
Feng.Net.Tcp.SocketClient.IPAdress Feng.Net.Tcp.SocketClient.LastRecvDataTime Feng.Net.Tcp.SocketClient.Name Feng.Net.Tcp.SocketClient.Path Feng.Net.Tcp.SocketClient.Port Feng.Net.Tcp.SocketClient.Session Feng.Net.Tcp.SocketClient._autoconnected Feng.Net.Tcp.SocketClient.autoconnectedevent
Feng.Net.Tcp.SocketClient.autonconnectthread Feng.Net.Tcp.SocketClient._client Feng.Net.Tcp.SocketClient._defaultwaitconnectiontime Feng.Net.Tcp.SocketClient._filetemppath Feng.Net.Tcp.SocketClient._hasconnected Feng.Net.Tcp.SocketClient._host Feng.Net.Tcp.SocketClient._index
Feng.Net.Tcp.SocketClient._ipaddress Feng.Net.Tcp.SocketClient._lastrecvdatatime Feng.Net.Tcp.SocketClient._name Feng.Net.Tcp.SocketClient.newclientobj Feng.Net.Tcp.SocketClient.objnewstarting Feng.Net.Tcp.SocketClient._path Feng.Net.Tcp.SocketClient._port
Feng.Net.Tcp.SocketClient.readonlyindex Feng.Net.Tcp.SocketClient.readonlyobject Feng.Net.Tcp.SocketClient.recvbuffer Feng.Net.Tcp.SocketClient.sendlist Feng.Net.Tcp.SocketClient._session Feng.Net.Tcp.SocketClient._userlist Feng.Net.Tcp.SocketClient.BeforeDataReceive
Feng.Net.Tcp.SocketClient.BeforeSendData Feng.Net.Tcp.SocketClient.ClientChanged Feng.Net.Tcp.SocketClient.ClosedConnected Feng.Net.Tcp.SocketClient.Connected Feng.Net.Tcp.SocketClient.DataReceived Feng.Net.Tcp.SocketClient.DownLoadFile Feng.Net.Tcp.SocketClient.FileRecvCompleted
Feng.Net.Tcp.SocketClient.FileRecving Feng.Net.Tcp.SocketClient.InitOnLineUsers Feng.Net.Tcp.SocketClient.OtherLogin Feng.Net.Tcp.SocketClient.RecviceUserData Feng.Net.Tcp.SocketClient.SessionChanged Feng.Net.Tcp.SocketClient.SystemMessageRecv Feng.Net.Tcp.SocketClient.TextRecv
MSQLCLIENT预置函数:
Feng.Net.Tcp.SqlClient.BeginQueryTable(string, Feng.Net.NetCallBacks.QueryTableCallBack) Feng.Net.Tcp.SqlClient.ColumnExists(string, string) Feng.Net.Tcp.SqlClient.ColumnExists(string, string, int) Feng.Net.Tcp.SqlClient.ExecuteSql(string) Feng.Net.Tcp.SqlClient.ExecuteSql(string, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.ExecuteSql(string, int) Feng.Net.Tcp.SqlClient.ExecuteSql(string, int, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.ExecuteSqlTran(System.Collections.Generic.List<string>) Feng.Net.Tcp.SqlClient.ExecuteSqlTran(System.Collections.Generic.List<Feng.Data.SqlClient.ModleInfo>) Feng.Net.Tcp.SqlClient.ExecuteSqlTran(System.Collections.Generic.List<string>, int) Feng.Net.Tcp.SqlClient.ExecuteSqlTran(System.Collections.Generic.List<Feng.Data.SqlClient.ModleInfo>, int) Feng.Net.Tcp.SqlClient.Exists(string) Feng.Net.Tcp.SqlClient.Exists(string, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.Exists(string, int) Feng.Net.Tcp.SqlClient.Exists(string, int, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.GetMaxID(string, string) Feng.Net.Tcp.SqlClient.GetMaxID(string, string, int) Feng.Net.Tcp.SqlClient.GetSingle(string) Feng.Net.Tcp.SqlClient.GetSingle(string, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.GetSingle(string, int) Feng.Net.Tcp.SqlClient.GetSingle(string, int, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.PostCallBac(System.IAsyncResult) Feng.Net.Tcp.SqlClient.Query(string) Feng.Net.Tcp.SqlClient.Query(string, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.Query(string, int) Feng.Net.Tcp.SqlClient.Query(string, int, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.QueryTable(string) Feng.Net.Tcp.SqlClient.SqlClient(System.Net.IPAddress, int) Feng.Net.Tcp.SqlClient.SqlClient() Feng.Net.Tcp.SqlClient.SqlClient(System.Net.IPAddress) Feng.Net.Tcp.SqlClient.SqlClient(string) Feng.Net.Tcp.SqlClient.TabExists(string) Feng.Net.Tcp.SqlClient.TabExists(string, int)
Feng.Net.Tcp.SqlClient.BeginQueryTable(string, Feng.Net.NetCallBacks.QueryTableCallBack) Feng.Net.Tcp.SqlClient.ColumnExists(string, string) Feng.Net.Tcp.SqlClient.ColumnExists(string, string, int) Feng.Net.Tcp.SqlClient.ExecuteSql(string) Feng.Net.Tcp.SqlClient.ExecuteSql(string, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.ExecuteSql(string, int) Feng.Net.Tcp.SqlClient.ExecuteSql(string, int, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.ExecuteSqlTran(System.Collections.Generic.List<string>) Feng.Net.Tcp.SqlClient.ExecuteSqlTran(System.Collections.Generic.List<Feng.Data.SqlClient.ModleInfo>) Feng.Net.Tcp.SqlClient.ExecuteSqlTran(System.Collections.Generic.List<string>, int) Feng.Net.Tcp.SqlClient.ExecuteSqlTran(System.Collections.Generic.List<Feng.Data.SqlClient.ModleInfo>, int) Feng.Net.Tcp.SqlClient.Exists(string) Feng.Net.Tcp.SqlClient.Exists(string, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.Exists(string, int) Feng.Net.Tcp.SqlClient.Exists(string, int, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.GetMaxID(string, string) Feng.Net.Tcp.SqlClient.GetMaxID(string, string, int) Feng.Net.Tcp.SqlClient.GetSingle(string) Feng.Net.Tcp.SqlClient.GetSingle(string, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.GetSingle(string, int) Feng.Net.Tcp.SqlClient.GetSingle(string, int, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.PostCallBac(System.IAsyncResult) Feng.Net.Tcp.SqlClient.Query(string) Feng.Net.Tcp.SqlClient.Query(string, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.Query(string, int) Feng.Net.Tcp.SqlClient.Query(string, int, params System.Data.SqlClient.SqlParameter[]) Feng.Net.Tcp.SqlClient.QueryTable(string) Feng.Net.Tcp.SqlClient.SqlClient(System.Net.IPAddress, int) Feng.Net.Tcp.SqlClient.SqlClient() Feng.Net.Tcp.SqlClient.SqlClient(System.Net.IPAddress) Feng.Net.Tcp.SqlClient.SqlClient(string) Feng.Net.Tcp.SqlClient.TabExists(string) Feng.Net.Tcp.SqlClient.TabExists(string, int)
评论(0)