欢迎光临
我们一直在努力

Visual C#建立简单消息传递系统(1)-.NET教程,C#语言

建站超值云服务器,限时71元/月

 摘要:本文讨论基于套接字(socket)的体系结构以及怎样建立一个高效的、易于使用的、可以同时在pc和pocket pc上运行的消息传递(message-passing)系统。

  套接字和消息

  目前,大多数web服务和所有的远程应用程序都使用了远程过程调用(remote-procedure-call,rpc)方法。你所做工作好像是在调用一个函数,但是在其后台执行了大量的操作以确保它在服务器上发生。在较低的层次,系统是在两台计算机之间传递消息,但这是不可视的。

  然而,当你转换到套接字操作的时候,你就在纯粹的基于消息的系统中编程了。这会改变你编写的代码的类型,因为读取返回的数据的唯一途径是通过消息。它与使用无返回值或输出参数的.net类有点类似,在这些情况下所有的返回信息都需要通过事件传递。

  由于我希望服务器程序告诉客户端什么时候应该改变曲目,使用消息就很有利,因为信息可以从服务器到达客户端,不需要客户端明确地请求该信息。但是,它要求你使用不同的方式达到目标。

  在解释所有操作之前,我想先谈论一点点安全性方面的问题。如果你在自己的计算机上打开了某个端口,其它人可能利用这个端口做不利的事情。他们可能希望写入没有意义的信号,以确定自己是否能够控制你的计算机或者使它崩溃。当你编写这类应用程序的时候考虑一下这种可能性是必要的。我的例子将运行在防火墙后面的网络上,所以我感觉到相对安全。

  简单的套接字

  我从建立一个服务器程序开始,它能给一个整数加上1,下面是服务器端代码:

public static void main()

{

ipaddress localaddr = ipaddress.parse("127.0.0.1");

tcplistener listener = new tcplistener(localaddr, 9999);

console.writeline("waiting for initial connection");

listener.start();

socket socket = listener.acceptsocket();

console.writeline("connected");

networkstream stream = new networkstream(socket);

binaryreader reader = new binaryreader(stream);

binarywriter writer = new binarywriter(stream);

int i = reader.readint32();

i++;

writer.write(i);

}

  它首先在本机的9999端口上建立了一个tcp监听器,接着启动监听器并等待连接。一旦得到了连接,它就接收一个整数,给它加1,并把它发送回去。

  需要指出的是我在此处使用的本地地址是127.0.0.1。在测试的时候这种情形可以很好地运行,这个时候客户端和服务器程序在相同的计算机上运行,但是当它们在不同的计算机上运行时,程序就不能运行了。在后面的部分中我将给出更复杂的代码。

 传递消息

  通过套接字传递未经处理的数据毫无乐趣,而通过套接字传递对象可能更有趣一些。为了达到这个目标,我们需要一个得到对象并把它转换为字节流的途径。最明显的解决方案是使用运行时(runtime)提供的串行化(serialization)支持。不幸的是,使用这种方法会有少量的问题。

  第一个问题是串行化需要很大的开销,这意味着它使用的字节比传递数据必要的字节多一些。如果使用soap格式化,这个问题就更严重。这是否成为一个问题依赖于应用程序的性能需求。第二个问题是串行化在简洁框架组件中不能使用。由于没有简单的实现方法,我们需要自己做这个工作。在这个过程中,我们做的事情比串行化要少多了。

  我们从建立一个枚举开始,它定义了可以传递什么类型的消息:

public enum messagetype

{

requestemployee = 1,

employee,

}

  对于每种消息类型,我们需要一个对象定义该对象:

public class requestemployee: isocketobject

{

int id;

public requestemployee(int id)

{

this.id = id;

}

}

public requestemployee(binaryreader reader)

{

id = reader.readint32();

}

public int id

{

get

{

return id;

}

}

public void send(binarywriter writer)

{

writer.write((int) messagetype.requestemployee);

writer.write(id);

}

}

  我们使用的这种途径与iserializable接口很相似。isocketobject接口定义了一个send()函数,它串行化通过通道的数据,接着还有一个并行化该数据的构造函数。

  在这些对象中的某个串行化自身的时候,它发送的第一个信息是消息标识符。它让接收者知道将到达哪种类型的对象并建立该对象。下面是客户端的代码:

requestemployee requestemployee = new requestemployee(15);

requestemployee.send(writer);

messagetype messagetype = (messagetype) reader.readint32();

switch (messagetype)

{

case messagetype.employee:

employee employee = new employee(reader);

console.writeline("{0} = {1}", employee.name, employee.address);

break;

}

  requestemployee这段代码建立了一个对象并把它发送给服务器程序,接着它找出返回的是哪种对象,并且并行化它。

  尽管这个示例项目被标记为client和server,但是两者之间唯一真正的差别是连接建立的方式。当这个过程完成后,它们都使用相似的代码发送和接收消息,即使它们需要处理自己的消息集合。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » Visual C#建立简单消息传递系统(1)-.NET教程,C#语言
分享到: 更多 (0)

相关推荐

  • 暂无文章