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

connect有个参数是struct sockaddr 所以可以用多个socket连接多个服务端。然后通过不同的socket给不同的服务器发送数据。还有你是不能直接操作服务器的。服务器只是根据你发送过去的特定数据进行响应。

一样的,弄个线程然后循环一直accept,判断:当有客户端链接的时候,就保存下来链接的这个客户端的socket,然后开个线程对这个socket发送数据就可以了。因为是循环accept就会有很多客户端链接过来。

进入mysql,创建一个新用户xuys:

格式:grant 权限 on 数据库名表名 用户@登录主机 identified by "用户密码";

grant select,update,insert,delete on to xuys@19216888234 identified by "xuys1234";

查看结果,执行:

use mysql;

select host,user,password from user;

可以看到在user表中已有刚才创建的xuys用户。host字段表示登录的主机,其值可以用IP,也可用主机名,

将host字段的值改为%就表示在任何客户端机器上能以xuys用户登录到mysql服务器,建议在开发时设为%。

update user set host = '%' where user = 'xuys';

2、 /mysqladmin -uroot -p21century reload

/mysqladmin -uroot -p21century shutdown

3、/mysqld_safe --user-root &

记住:对授权表的任何修改都需要重新reload,即执行第3步。

如果经过以上3个步骤还是无法从客户端连接,请执行以下操作,在mysql数据库的db表中插入一条记录:

use mysql;

insert into db values('19216888234','%','xuys','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');

update db set host = '%' where user = 'xuys';

重复执行上面的第2、3步。

C/S分布式模式,是计算机用语。C是指Client,S是指Server。C/S模式就是指客户端/服务器模式。是计算机软件协同工作的一种模式。由于Web浏览器的兴起,B/S模式逐步取代了C/S模式,被更广泛地应用。

根据客户/服务器(Client/Server简记为C/S)体系结构的概念,至少用两台计算机来分别充当客户机和服务器角色。

C/S服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,如Oracle、Sybase、Informix或SQL Server。客户端需要安装专用的客户端软件。

扩展资料:

C\S客户端优点:

1、C/S功能强大,可以减轻服务器端压力,如果用户的需求特别复杂,用C/S。

2、C/S程序可以更加注重流程,可以对权限多层次校验,对系统运行速度可以较少考虑。

3、C/S一般建立在专用的网络上,小范围里的网络环境,局域网之间再通过专门服务器提供连接和数据交换服务。

4、C/S一般面向相对固定的用户群,对信息安全的控制能力很强.一般高度机密的信息系统采用C/S结构适宜.可以通过B/S发布部分可公开信息。

由于客户端IP被写入程序,所以在不动源代码的情况下不能更改,只好从服务器端想办法。

有几个方式可以实现:

一、服务器接入路由器,由路由器来连接不同网段,在其内设置虚拟专网。

二、服务器安装两块网卡。

三、你就不会再弄台计算机做以前IP地址的服务器啊~

四、实在不行,你就直接在客户机上安装虚拟服务器好了。

以上各具体部骤恕我不详细说明,够写一本书了……自己上网搜吧。

看看是不是IP地址没有设置在同一子网

防火墙有没有关闭

-----------------------------

那就可能是你XP服务器端监听没有成功

1确认你的服务端启动正常,包括监听的端口是否正确打开,有可能是你的端口被占用。

2客户端连接的ip地址和端口是否正确。

3确认你自己电脑的网络正常,包括网卡驱动是否安装正常,是否支持tcp/ip协议。

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

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情