这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上。

根据上一篇文章介绍的Slice语法,我们先来定义ICE文件。我定义两个ICE文件,一个用来描述测试数据库表中属性相关信息,另一个则是请求数据的方法。

结构如下:

  

定义结构体,和数据库中表的列对应,添加序列(相当于数组类型)。

在获取表的方法中注意要记得#include带有结构的ice文件,并把接口函数的返回值类型写成之前定义的数组类型,否则就像HelloWorld例子中只能在服务器显示,调回不到客户端了。(DbTableDataSeq getDataFromDb(string requestCode);这个方法其实就是客户端一调用,然后服务器操作完成,最后返回DbTableDataSeq类型的数据)

编译ICE文件:

在数据库中随便插入几条数据:

之后是一系列基本工作:创建工程,添加对ICE的引用,拖入编译好的文件,对具有接口函数的ICE文件创建实现类,实现抽象类DoSelectTableDisp_

大体结构如下图:              

为了结构能更清晰,我们把它改成这样,同时添加上查询数据库的方法:

给出这几个类的代码如下:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleSer.common
{
public class DbData
{
public string dataName;//数据库中列名
public object dataValue;//数据库中列值
} public class DbDataList
{
public IList<DbData> dataRow;
}
}
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleSer.common;
using IBM.Data.DB2;
using System.Data; namespace ConsoleSer.database
{
public class Db2:DbMain
{
public override IList<DbDataList> GetDataFromDatabase(string strSql)
{
IList<DbDataList> list = new List<DbDataList>(); using (DB2Connection con = new DB2Connection("server=127.0.0.1;database=TEST;uid=db2admin;pwd=db2admin;"))
{
con.Open();
DB2DataAdapter oda = new DB2DataAdapter(strSql, con);
DataSet ds = new DataSet();
oda.Fill(ds);
if (ds.Tables.Count > )
{
DataTable dt = ds.Tables[];
for (int i = ; i < dt.Rows.Count; i++)
{
IList<DbData> rowsData = new List<DbData>();
for (int j = ; j < dt.Columns.Count; j++)
{
DbData data = new DbData();
data.dataName = dt.Columns[j].ColumnName;
data.dataValue = dt.Rows[i][data.dataName];
rowsData.Add(data);
}
DbDataList rows = new DbDataList();
rows.dataRow = rowsData;
list.Add(rows);
}
}
}
return list;
}
}
}
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleSer.common; namespace ConsoleSer.database
{
public class DbMain
{
public virtual IList<DbDataList> GetDataFromDatabase(string strSql)
{
IList<DbDataList> list = new List<DbDataList>();
return list;
}
}
}

最终查询完数据库返回的是这样的一条数据:(IList<DbDataList> list = new List<DbDataList>(); DbDataList包含两个字段string dataName;object dataValue;)

但是这并不是我们想要的返回类型,我们再将其转换为DbTableData类型数组,于是在TestTableMethodI实现类中有如下代码(假设客户端请求字符串是getTable):

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using tableStructFamily;
using ConsoleSer.common;
using ConsoleSer.database; namespace ConsoleSer.slice2csI
{
class TestTableMethodI:DoSelectTableDisp_
{
public static List<DbTableData> tbData = new List<DbTableData>();//数据库中表信息
private static DbMain dbObject = new Db2(); public override DbTableData[] getDataFromDb(string requestCode, Ice.Current current__)
{
if (requestCode == "getTable")
{
Console.WriteLine("收到请求!");
return selectDataFromDb();
}
else
{
throw new Exception();
}
} private DbTableData[] selectDataFromDb()
{
IList<DbDataList> list = dbObject.GetDataFromDatabase("select * from A.T_test"); DbTableData[] objs = new DbTableData[list.Count]; for (int i = ; i < list.Count; i++)
{
DbDataList row = list[i];
DbTableData obj = GetTableObj(row);
tbData.Add(obj);
objs[i] = obj;
}
return objs;
} private DbTableData GetTableObj(DbDataList dataRow)
{
DbTableData obj = new DbTableData();
for (int i = ; i < dataRow.dataRow.Count; i++)
{
DbData data = dataRow.dataRow[i];
setObjValue(data, ref obj);
}
return obj;
} private void setObjValue(DbData data, ref DbTableData obj)
{
string name = data.dataName.ToLower();
switch (name)
{
case "id":
obj.ID = Convert.ToInt32(data.dataValue);
break;
case "nname":
obj.Nname = data.dataValue.ToString();
break;
default:
break;
}
}
}
}

附上Main函数初始化ICE的方法:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using tableStructFamily; namespace ConsoleTestIceServer
{
class Program
{
static void Main(string[] args)
{
int status = ;
Ice.Communicator ic = null;
try
{
ic = Ice.Util.initialize(ref args);
Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("tableSelector", "default -p 10000");
Ice.Object obj = new ConsoleSer.slice2csI.TestTableMethodI();
adapter.add(obj, Ice.Util.stringToIdentity("tableSelector"));
adapter.activate();
Console.WriteLine("初始化成功!");
ic.waitForShutdown();
}
catch (Exception e)
{
Console.Error.WriteLine(e);
status = ;
}
finally
{
if (ic != null)
{
ic.destroy();
}
}
Environment.Exit(status);
}
}
}

如此一来服务端代码就写好了。

很少用BD2数据库,一直用SqlServer编译时报了如下警告,不能运行:

在网上搜索了一下:改成了.NET Framwork4,没有后面的Client Profile,就可以用了;这个修改需要右击项目,然后选择其中的属性。

接下来我们编写客户端代码:

与服务端相同一开始是一系列基本工作:创建工程,添加对ICE的引用,拖入编译好的文件

大体结构如下图:

在Form上添加三个控件:

给出完整客户端代码:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using tableStructFamily; namespace FormCli
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void btnSendRequestCode_Click(object sender, EventArgs e)
{
int status = ;
Ice.Communicator ic = null;
try
{
ic = Ice.Util.initialize();
txtShowMsg.AppendText("初始化成功!\r\n");
Ice.ObjectPrx obj = ic.stringToProxy("tableSelector:default -p 10000");
DoSelectTablePrx selector = DoSelectTablePrxHelper.checkedCast(obj);
if (selector == null)
{
throw new ApplicationException("Invalid proxy");
}
txtShowMsg.AppendText("开始发送请求!\r\n");
DbTableData[] objs = selector.GetDataFromDb("getTable");
txtShowMsg.AppendText("发送请求成功!\r\n"); if (objs.Length > )
{
txtShowMsg.AppendText("成功获取数据!\r\n");
} foreach (DbTableData td in objs)
{
txtShowMsg.AppendText(td.id.ToString() + "\r\n");
txtShowMsg.AppendText(td.nName.ToString() + "\r\n");
} DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Nname");
foreach (DbTableData td in objs)
{
DataRow dr = dt.NewRow();
dr["ID"] = td.id;
dr["Nname"] = td.nName;
dt.Rows.Add(dr);
} dgvShowTable.DataSource = dt; //显示到gridview中
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
status = ;
}
finally
{
if (ic != null)
ic.destroy();
}
txtShowMsg.AppendText(status.ToString());
//Environment.Exit(status);
} }
}

DoSelectTablePrx selector = DoSelectTablePrxHelper.checkedCast(obj);

DbTableData[] objs = selector.GetDataFromDb("getTable");

这两行代码是客户端能获取服务器上数据的关键,客户端与服务器调用相同的函数,通过返回值类型,客户端就能够从服务器上得到返回的数据。

最终运行结果如下:

ICE学习第四步-----客户端请求服务器返回数据的更多相关文章

  1. Koa2学习(四)POST请求

    Koa2学习(四)POST请求 接受请求 POST请求的数据实体,会根据数据量的大小进行分包传送. 当node.js后台收到post请求时,会以buffer的形式将数据缓存起来.Koa2中通过ctx. ...

  2. C# FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址。"的错误

    FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址."的错误 解决方法是在原代码上增加这句话 reqFTP.UsePassive = f ...

  3. Postman----模拟服务器返回数据

    使用场景:在某些情况下,比如A接口还没开发好,我们需要测试B接口,刚好B接口的请求数据中需要包含A接口返回的数据,这时我们就可以模拟A接口服务器返回的数据来测试B接口 解决办法: 举例:模拟此 htt ...

  4. 02 - Unit01:服务器返回数据的json处理+搭建项目环境

    服务器返回数据的json处理+搭建项目环境 服务器返回数据的json处理 springMVC JSP响应流程 请求 -->DispatcherServlet -->HandlerMappi ...

  5. js进阶ajax读取json数据(ajax读取json和读取普通文本,和获取服务器返回数据(链接)都是一样的,在url处放上json文件的地址即可)

    js进阶ajax读取json数据(ajax读取json和读取普通文本,和获取服务器返回数据(链接)都是一样的,在url处放上json文件的地址即可) 一.总结 ajax读取json和读取普通文本,和获 ...

  6. asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。

    原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...

  7. charles技能之修改请求参数/返回数据(map Local、Rewrite、Breakpoints)

    之前一直用postman调接口比较多,但有时候想要去修改APP的页面展示,造数据又会比较麻烦,此时可以用以下三种方法修改请求参数或修改响应: map Local(本地映射).Breakpoints(打 ...

  8. ICE学习第三步-----Slice语言

    ICE:Slice语言(一)-编译 Introduce简介 Slice(Specification language for ice)是分离对象和对象的实现的基础的抽象机制.Slice在客户端和服务器 ...

  9. MongoDB学习(四)客户端工具备份数据库

    在上一篇MongoDB学习(三)中讲解了如何在服务器端进行数据的导入导出与备份恢复,本篇介绍下如何利用客户端工具来进行远程服务器的数据备份到本地. 以客户端工具MongoVUE为例来进行讲解: 1.首 ...

随机推荐

  1. Hibernate(四)基本映射

    映射的概念 在上次的博文Hibernate(三)Hibernate 配置文件我们已经讲解了一下 Hibernate中的两种配置文件,其中提到了两种配置文件的主要区别就是XML可以配置映射.这里提到的映 ...

  2. Bzoj 2818: Gcd 莫比乌斯,分块,欧拉函数,线性筛

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3241  Solved: 1437[Submit][Status][Discuss ...

  3. 佛山Uber优步司机奖励政策(1月25日~1月31日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. java 检查是否是数组 检查是否是空数组 检查数组是否包含某个元素

    /** * Determine whether the given object is an array: * either an Object array or a primitive array. ...

  5. linux OpenOffice

    1.下载所需的安装包  /project/openofficeorg.mirror/4.0.1/binaries/zh-CN/Apache_OpenOffice_4.0.1_Linux_x86-64_ ...

  6. c#基础语言编程-多态

    语言中的多态性是为了使程序有扩展性,为实现多态性,在程序中体现为接口.抽象类.父类.具体类. 接口就是一种规范,解决了多重继承的问题,类似一种规范,告诉我要做什么,具有什么能力,在接口中定义写行为属性 ...

  7. javascript弹出框打印某个数值时,弹出NaN?(not a number)

    一.NaN:表示not a number null 未定义或空字符串 undefined 对象属性不存在 或是声明了变量但从未赋值. 二.出现这种情况有(1)此常数的值是零被零除所得到的结果. (2) ...

  8. ExtractNewFolderPath

    unit Unit1; interface uses  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,  Syst ...

  9. android 55

    智能家居:可以联网可以用指令操作可以返回状态.智能微波炉智能眼镜智能手表. Android作者Andy Rubin,2007年正式由谷歌推广,开源的. 安卓体系结构和开发一个闹钟的调用结构图: 安卓和 ...

  10. android 35 ListView增删改差

    MainActivity package com.sxt.day05_11; import java.util.ArrayList; import java.util.List; import and ...