C# 怎样才能实现客户端通过服务器端连接数据库服务器???

C# 怎样才能实现客户端通过服务器端连接数据库服务器???,第1张

可以处理的,步骤为:

1客户端服务器连(用Socket通讯)

2客户端向处服务器发送SQL语句,如搜索一个表的数据

3服务器接到请求,执行SQL语句返回一个DataTable

4服务器将这个DataTable进行序列化、并且压缩

5服务器将序列化和压缩后的byte[] msg数组传给客户端

6客户端收到byte[] msg数组先进行解压缩、和反序列化为DataTable

7再将DataTable通过DataSet和SqlDataAdapterUpdate(Table)存在SQL中

下面我只给一些关键的代码,我有实现过的

第一步客户端==》连接服务器并通讯,主要是发送SQL给服务器返回一个DataTable表

using System;

using SystemCollectionsGeneric;

using SystemComponentModel;

using SystemData;

using SystemDrawing;

using SystemLinq;

using SystemText;

using SystemWindowsForms;

using SystemNet;

using SystemNetSockets;

using SystemXml;

using SystemXmlSerialization;

using SystemIO;

using SystemIOCompression;

namespace Client

{

public partial class FormClient : Form

{

DataTable dt;

public FormClient()

{

InitializeComponent();

}

private void ClientTest(string str)

{

Socket client;

String returnData;

byte[] buf = new byte[9991024]; //此处可能有些问题

//IPAddress local = IPAddressParse("1162583127");

IPAddress local = IPAddressParse("127001");//可改为远程IP地址

IPEndPoint iep = new IPEndPoint(local, 6060);

try

{

client = new Socket(AddressFamilyInterNetwork, SocketTypeStream, ProtocolTypeTcp);

clientConnect(iep);

}

catch (SocketException)

{

ConsoleWriteLine("无法连接到服务器!");

return ;

}

//输入exit,可以断开与服务器的连接

if (str == "")

{

return;

}

//发送SQL语句给服务器

clientSend(EncodingUnicodeGetBytes(str));

//得到实际收到的字节总数

Int32 rec = clientReceive(buf);

ConsoleWriteLine(EncodingASCIIGetString(buf, 0, rec));

//接收服务器返回的数据

returnData = SystemTextEncodingUnicodeGetString(buf,0,rec);

//将returnData解压缩后,再反序列化转成DataTable dt = DeserializerDataTable(Decompress(returnData));

ConsoleWriteLine("断开与服务器的连接");

clientClose();

dataGridView1DataSource = dt;

}

//将DataTable表反序列化

private DataTable DeserializerDataTable(string pXml)

{

StringReader strReader = new StringReader(pXml);

XmlReader xmlReader = XmlReaderCreate(strReader);

XmlSerializer serializer = new XmlSerializer(typeof(DataTable));

DataTable dt = serializerDeserialize(xmlReader) as DataTable;

return dt; }

//给服务器传SQL语句

private void buttonSearch_Click(object sender, EventArgs e)

{

string Sql = StringFormat("Select top {0} From Part Where CorpCode_='PT'", textBox1TextTrim()); ;

ClientTest(Sql);

}

#region 压缩和解压缩

public string Compress(string str)

{

byte[] buffer = EncodingUnicodeGetBytes(str);

MemoryStream ms = new MemoryStream();

using (GZipStream zip = new GZipStream(ms, CompressionModeCompress, true))

{

zipWrite(buffer, 0, bufferLength);

}

msPosition = 0;

MemoryStream outStream = new MemoryStream();

byte[] compressed = new byte[msLength];

msRead(compressed, 0, compressedLength);

byte[] gzBuffer = new byte[compressedLength + 4];

SystemBufferBlockCopy(compressed, 0, gzBuffer, 4, compressedLength);

SystemBufferBlockCopy(BitConverterGetBytes(bufferLength), 0, gzBuffer, 0, 4);

return ConvertToBase64String(gzBuffer);

}

//解压缩

public string Decompress(string compressedText)

{

byte[] gzBuffer = ConvertFromBase64String(compressedText);

using (MemoryStream ms = new MemoryStream())

{

int msgLength = BitConverterToInt32(gzBuffer, 0);

msWrite(gzBuffer, 4, gzBufferLength - 4);

byte[] buffer = new byte[msgLength];

msPosition = 0;

using (GZipStream zip = new GZipStream(ms, CompressionModeDecompress))

{

zipRead(buffer, 0, bufferLength);

}

return EncodingUnicodeGetString(buffer);

}

}

#endregion

}

}

第二步服务器收到SQL语句执行,并回传一个表给客户端

服务器接到请求,执行SQL语句返回一个DataTable

服务器将这个DataTable进行序列化、并且压缩

服务器将序列化和压缩后的byte[] msg数组传给客户端

using System;

using SystemCollectionsGeneric;

using SystemComponentModel;

using SystemData;

using SystemDrawing;

using SystemLinq;

using SystemText;

using SystemWindowsForms;

using SystemNet;

using SystemNetSockets; //可以使用套接字

using SystemThreading; //可以使用多线程

using SystemDataSqlClient;

using SystemXml;

using SystemXmlSerialization;

using SystemIO;

using SystemIOCompression;

namespace AppServer

{

public partial class FormApp : Form

{

public FormApp()

{

InitializeComponent();

}

private void FormApp_Load(object sender, EventArgs e)

{

// AppService instance = new AppService();

}

private void buttonStartService_Click(object sender, EventArgs e)

{

AppService();

}

private Socket server;

private Socket client;

private void AppService()

{

/

//本机IP

string name = DnsGetHostName();

IPHostEntry host = DnsGetHostByName(name);

IPAddress id= hostAddressList[0];

/

//IPAddress local = IPAddressParse("1921680100");

IPEndPoint iep = new IPEndPoint(IPAddressAny, 6060);

server = new Socket(AddressFamilyInterNetwork, SocketTypeStream, ProtocolTypeTcp);

// 将套接字与本地终结点绑定

serverBind(iep);

//在本地13000端口号上进行监听

serverListen(10);

while (true)

{

// 得到包含客户端信息的套接字

client = serverAccept();

//创建消息服务线程对象ClientService方法委托给线程

Thread newthread = new Thread(new ThreadStart(ClientService));

// 启动消息服务线程

newthreadStart();

}

}

private Int32 i;

private void ClientService()

{

Socket s = client;

String data = null;

String returnData = null;

byte[] bytes = new byte[1024];

while ((i = sReceive(bytes)) != 0)

{

//接收客户端的SQL

data = SystemTextEncodingUnicodeGetString(bytes, 0, i);

//将接到的String 执行SQL返回表

DBAccess obj = new DBAccess(); //专门传给SQL的类相当于DBHELP

DataTable dt = objFillData(data, "TEST", 1);//执行SQL返回表

//将返回的表转为String,并将returnData压缩

returnData = objCompress(objSerializeDataTableXml(dt));

byte[] msg = SystemTextEncodingUnicodeGetBytes(returnData);

// 发送数据表给客户端 sSend(msg);

if ((i = sReceive(bytes)) == 0)

continue;

}

//关闭套接字

sClose();

}

}

//DBAccess的部份代码

class DBAccess

{

#region DataTable序列化与反序列化

public string SerializeDataTableXml(DataTable dt)

{

StringBuilder sb = new StringBuilder();

XmlWriter writer = XmlWriterCreate(sb);

XmlSerializer serializer = new XmlSerializer(typeof(DataTable));

serializerSerialize(writer, dt);

writerClose();

return sbToString(); }

public DataTable DeserializerDataTable(string pXml)

{

StringReader strReader = new StringReader(pXml);

XmlReader xmlReader = XmlReaderCreate(strReader);

XmlSerializer serializer = new XmlSerializer(typeof(DataTable));

DataTable dt = serializerDeserialize(xmlReader) as DataTable;

return dt; }

#endregion

#region 压缩和解压缩

public string Compress(string str)

{

byte[] buffer = EncodingUnicodeGetBytes(str);

MemoryStream ms = new MemoryStream();

using (GZipStream zip = new GZipStream(ms, CompressionModeCompress, true))

{

zipWrite(buffer, 0, bufferLength);

}

msPosition = 0;

MemoryStream outStream = new MemoryStream();

byte[] compressed = new byte[msLength];

msRead(compressed, 0, compressedLength);

byte[] gzBuffer = new byte[compressedLength + 4];

SystemBufferBlockCopy(compressed, 0, gzBuffer, 4, compressedLength);

SystemBufferBlockCopy(BitConverterGetBytes(bufferLength), 0, gzBuffer, 0, 4);

return ConvertToBase64String(gzBuffer);

}

public string Decompress(string compressedText)

{

byte[] gzBuffer = ConvertFromBase64String(compressedText);

using (MemoryStream ms = new MemoryStream())

{

int msgLength = BitConverterToInt32(gzBuffer, 0);

msWrite(gzBuffer, 4, gzBufferLength - 4);

byte[] buffer = new byte[msgLength];

msPosition = 0;

using (GZipStream zip = new GZipStream(ms, CompressionModeDecompress))

{

zipRead(buffer, 0, bufferLength);

}

return EncodingUnicodeGetString(buffer);

}

}

#endregion

}

第三步调用DataSet和SqlDataAdapterUpdate(Table)存在SQL中,这个是传入一个DataGridView ,可在客户端中使用保存(部份代码,没有连接SQL数据库的)

#region 公共保存DataGridView

public bool DataGridViewSave(DataTable table,string tableName,string CorpCode)

{

string Sql = StringFormat("Select Top 0 From {0} Where CorpCode_='{1}' ", tableName, CorpCode);

SqlDataAdapter sda = new SqlDataAdapter(thisCreateCommand(Sql, null, 1));

SqlCommandBuilder scb = new SqlCommandBuilder(sda);

sdaUpdate(table);

thisClose();

return true;

}

#endregion

据Samba项目网站声称,Samba是一组开源/免费软件套件,它为SMB/CIFS客户机提供了无缝顺畅的文件和打印服务。不像实现SMB/CIFS网络协议的其他系统(比如面向HP-UX的LM Server、面向OS/2的LAN Server或VisionFS),Samba(及其源代码)可以免费获取(最终用户不需要支付任何费用),并且允许Linux/Unix服务器和Windows/Unix/Linux客户机之间实现协同运行。

正是由于这些原因,在不同的操作系统(并非仅仅只有Linux)共存的网络环境下,Samba是文件服务器的优选解决方案――而最常见的网络架构就是多个微软Windows客户机访问一台安装有Samba的Linux服务器,我们将在本文中探讨这种情形。

要注意:另一方面,如果我们的网络完全由基于Unix的客户机(比如Linux、AIX或Solaris等等)组成,可以考虑使用NFS(不过在这种情况下Samba仍是一种选择),这时NFS的速度更快。

将Samba安装在Debian和CentOS上

在我们开始着手安装之前,可以使用操作系统的软件包管理系统,寻找关于Samba的信息:

在Debian上:

# aptitude show samba

在CentOS上:

# yum info samba

在下面这个屏幕截图中,我们可以看到“aptitude show samba”的输出结果(“yum info samba”会得到类似的结果):

现在不妨安装Samba(下面这个屏幕截图对应于安装到Debian 7 [Wheezy]服务器上的情况):

在Debian上:

# aptitude install samba

在CentOS上:

# yum install samba

将用户添加到Samba

如果是4x之前的版本,想将用户添加到Samba,就需要一个本地Unix帐户:

# adduser <username>

下一步,我们需要使用带“-a”选项的smbpasswd命令,将用户添加到Samba,该选项指定随后用户名应添加到本地smbpasswd文件。系统会提示我们输入一个密码(该密码没必要与本地Unix帐户的密码一样):

# smbpassword -a <username>

最后,我们将访问系统中用作Samba共享区的一个目录的权限授予用户xmodulo(如果需要的话,还可以将访问权限授予其他用户)。要完成这一步,只需用文件编辑器(比如Vim)打开/etc/samba/smbconf文件,浏览到文件末尾,使用描述性名称,创建一段代码(将名称括在方括号内),比如[xmodulo]:

# SAMBA SHARE [xmodulo] path = /home/xmodulo available = yes valid users = xmodulo read only = no browseable = yes public = yes writeable = yes

现在我们必须重启Samba;为了以防万一,使用testparm命令检查smbconf文件,查找有无语法错误:

# service samba restart # testparm

要是有什么错误,testparm结束运行后,就会如实报告。

将Samba共享区映射为Windows 7 PC上的网络驱动器

鼠标右击Computer(电脑),选择“Map network drive”(映射网络驱动器):

键入安装有Samba的那台机器的IP地址,随后键入共享区的名称(这是smbconf文件中刮在单括号内的名称),并确保“Connect using different credentials”(使用不同的登录资料来连接)复选框已勾选:

输入之前用“smbpasswd -a”设置的用户名和密码:

进入到Computer(电脑),检查网络驱动器是否已正确添加上去:

为了测试一下,不妨利用Samba的参考手册页创建一个PDF文件,并将它保存到/home/xmodulo目录中:

下一步,我们可以证实该文件可以从Windows来进行访问:

我们可以使用默认的pdf阅读软件打开该文件:

最后,不妨看一下我们能否将来自Windows的一个文件保存到刚映射的网络驱动器。我们将打开changelog文件,该文件列出了Notepad++的功能特性:

然后试着将它作为一个明文文件(txt扩展名)保存到Z:\;然后,不妨看一下该文件在Linux中是否能浏览:

启用配额

第一步,我们需要证实当前内核是不是已经过编译并支持配额:

# cat /boot/config-$(uname -r) | grep -i config_quota

每一个文件系统最多有五种配额限制可予以实施:用户软限制、用户硬限制、用户组软限制、用户组硬限制和宽限时间。

现在我们将为/home文件系统启用配额,为此在/etc/fstab文件中对应/home文件系统的那一行,将usrquota和grpquota挂载选项添加到现有的defaults选项;为了让变更生效,我们将重新挂载文件系统:

下一步,我们需要在/home中创建两个文件,它们将充当用户配额和用户组配额的数据库:分别是aquotauser和aquotagroup。之后,我们将针对启用配额的文件系统,创建当前磁盘使用表:

# quotacheck -cug /home # quotacheck -avugm

尽管我们已为/home文件系统启用了配额,但我们还没有对任何用户或用户组设置任何限制。检查现有用户/用户组的配额信息:

# quota -u <username> # quota -g <groupname>

最后,后几步包括:使用quotatool命令,为每个用户及/或每个用户组指定配额(注意:可以使用edquota来执行这项任务,但quotatool更直观简单,不太容易出错)。

想为名为xmodulo的用户将软限制设置在4 MB、将硬限制设置在5 MB,并为xmodulo用户组将软限制和硬限制分别设置在10 MB和15 MB:

# quotatool -u xmodulo -bq 4M -l '5 Mb' /home # quotatool -g xmodulo -bq 10M -l '15 Mb' /home

其实这个很简单

只要你的服务器和客户机的IP设置在同一网段就可以了啊,把路由器的LAN口当交换机使用就OK了

比如你服务器IP 19216812 客户机IP 19216813-254就行了,同一网段

掩码 2552552550 这样客户机就能连到服务器了

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » C# 怎样才能实现客户端通过服务器端连接数据库服务器???

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情