如何实现基于socket传输的C/S程序架构设计

时间:2021-11-10 19:42:25
 小弟手里最近有个一个项目想用c#来做,因为过程需要和硬件设备进行数据交换,采用C/S设计比较好。由于以前都的程序都是使用的程序  < - > 数据库 的模式,未有多客户端加服务器的模式。这个程序需要和内网机外网的客户端进行通讯。socket方面自己没有问题,但是在关于程序架构设计方面自己一直很困惑,所以来到这里寻求帮助,希望前辈们能够不吝赐教,指点迷津!
  项目整体的架构是 客户端 -- 服务器 --- 数据库 的模式,服务器使用Sql server ,客户端通过socket从服务器获取数据而不直接访问数据库(这个涉及到数据同步问题,所以不能直接访问数据库,否则会产生“脏数据”的可能)。服务器的设计结构为数据访问层(DAL)、业务逻辑层(BLL)和传输控制层(TCL),客户端采用缓冲机制,客户机正常联网时数据实时传输,一旦断网可以缓存到本地,再次连接到服务器时同步上传。小弟的困惑是:
1、客户端和服务器端采用异步TCP协议,二者需要定义个协议,如何实现这个协议确保数据稳定传输?我的想法是:定义一个传输对象,TransferObject, 该对象包含客户端的编号,请求编号,服务器处理编号,请求的命令,附加的数据。客户端请求数据时封装一个对象,把自己的编号,请求的编号(GUID),命令,命令附加数据放到对象里面。服务器收到这个对象后进行解析,然后把执行结果也封装一个对象返回给客户端。现在的问题是由于采用异步传输,服务器如何验证客户端数据发送完了,并且验证数据的完整性?服务器给客户端发送数据时有两种方式:一、使用已经建立的客户端的socket发送,客户端如何知道服务器已经把数据返回了;二、客户端也有自己的监听端口,服务器把处理结果发送至该端口,客户端收到这个数据时怎么去和前期的那个请求命令进行关联处理?
2、按照程序设计的思想,一般都是高层组件调用底层。网络传输层应该视为底层,只是负责数据传输,应该被其他模块调用,如何实现控制层对网络传输层的控制,而不是网络传输层调用控制层?另外,如果不好实现是否应该把传输和控制合并到一个模块里面?
本人刚刚接触这个领域,希望各位前辈不要见效,并能够给予多多指导!如果能够提供实例就更好了!谢谢!
  如何实现基于socket传输的C/S程序架构设计

13 个解决方案

#1


基本正确吧,定好自己的协议,就可以开始做事儿了,一下子也不可能做太好,必须自己动手实践才能学到东西;

#2


同意楼上说法。

#3


我原来也做这个,但由于只做了客户端,给你提供一些方法:
一:如何判断数据传输完成,在传输命令开始的时候加上总共的长度,例如:SA000020,TESTSTESTES
   前面两位表示命令,后面表示长度
二:一般客户端不用监控一个端口,因为不可能要求客户端网络稳定,如果网络堵塞会造成服务器资源浪费,建议在客户端连接服务器时处理所有没有完成的事情.

#4


协议格式你自己定义好,你的Server能处理就行了

#5


引用 3 楼 lzhzxl 的回复:
我原来也做这个,但由于只做了客户端,给你提供一些方法:
一:如何判断数据传输完成,在传输命令开始的时候加上总共的长度,例如:SA000020,TESTSTESTES
   前面两位表示命令,后面表示长度
二:一般客户端不用监控一个端口,因为不可能要求客户端网络稳定,如果网络堵塞会造成服务器资源浪费,建议在客户端连接服务器时处理所有没有完成的事情.

一般怎么定义传输协议呢?另外服务器端到底怎么来控制?

#6


引用楼主 qqaoshi888 的回复:
二、客户端也有自己的监听端口,服务器把处理结果发送至该端口,客户端收到这个数据时怎么去和前期的那个请求命令进行关联处理

我认为是,客户端的与请求命令的关联一般好处理,多半是单一命令,或者数个命令。
而困难的恰恰是服务器端,服务器可能同时对多客户提供服务,那么就应该建立一个命令表,对应到各个客户,那些客户的命令还在队列中,那些是正在处理中的命令。那些命令被处理完了,需要返回相应信息到对应客户。
在我的系统中,这个命令表,及服务器提供的常用服务定义,可以看成时连接业务逻辑层和底层网络传输层的纽带,2个层通过这个来交互。

#7


引用楼主 qqaoshi888 的回复:
一、使用已经建立的客户端的socket发送,客户端如何知道服务器已经把数据返回了;

这个一般可以通过你定义的协议包来判断,判断服务器数据返回,数据完整性的。如果没有返回,那客户端应该定义超时处理请求机制,必要的数据在保证网络无故障的情况下,可以考虑重发等其他方式。

#8


说说我的想法:
1.如果你这样分层的话 客户端假如有数据存储的话应该放在哪呢 比如XML文档或是其他一些形式的存储
2.服务器端这样分 直观上看是一种串联的形式 也就是有了你的想法(控制和传输谁先谁后的问题) 如果把通讯层分离开来呢 他和服务器形成一种并联的形式 把通讯抽出来作为一个子系统

#9


引用 7 楼 yyd021 的回复:
引用楼主 qqaoshi888 的回复:
一、使用已经建立的客户端的socket发送,客户端如何知道服务器已经把数据返回了;

这个一般可以通过你定义的协议包来判断,判断服务器数据返回,数据完整性的。如果没有返回,那客户端应该定义超时处理请求机制,必要的数据在保证网络无故障的情况下,可以考虑重发等其他方式。

谢谢您的指导。我的意图好像没有阐述清楚,下面我就说个例子吧:
客户端调用  Dataset GetUserList() 获取用户列表,该函数里面会创建一个socket,然后使用networkstream写入要查询的命令及内容,服务器收到后把执行结果再通过networkstream写入执行结果。我的疑问是客户端的socket的发送是由程序员控制的,但是怎么样通过该networkstream自动获得服务器的执行结果呢?

#10


如果数据传输的性能要求不是很高,数据的传输可以考虑使用WCF,比直接使用socket应该容易多了。

#11


上面是以前同事的建议

#12


引用 10 楼 yishanhai 的回复:
如果数据传输的性能要求不是很高,数据的传输可以考虑使用WCF,比直接使用socket应该容易多了。

我用的.NET 2.0 ,WCF需要使用3.0

#13


你要直接基于Socket编程的话,发送数据必须写Sokcet的Send或BeginSend命令。
要接收数据的话,同样服务器端必须Receive或BeginReceive命令。
你可以在DataSet类中添加一个事件,处理接收到服务器返回的结果。

#1


基本正确吧,定好自己的协议,就可以开始做事儿了,一下子也不可能做太好,必须自己动手实践才能学到东西;

#2


同意楼上说法。

#3


我原来也做这个,但由于只做了客户端,给你提供一些方法:
一:如何判断数据传输完成,在传输命令开始的时候加上总共的长度,例如:SA000020,TESTSTESTES
   前面两位表示命令,后面表示长度
二:一般客户端不用监控一个端口,因为不可能要求客户端网络稳定,如果网络堵塞会造成服务器资源浪费,建议在客户端连接服务器时处理所有没有完成的事情.

#4


协议格式你自己定义好,你的Server能处理就行了

#5


引用 3 楼 lzhzxl 的回复:
我原来也做这个,但由于只做了客户端,给你提供一些方法:
一:如何判断数据传输完成,在传输命令开始的时候加上总共的长度,例如:SA000020,TESTSTESTES
   前面两位表示命令,后面表示长度
二:一般客户端不用监控一个端口,因为不可能要求客户端网络稳定,如果网络堵塞会造成服务器资源浪费,建议在客户端连接服务器时处理所有没有完成的事情.

一般怎么定义传输协议呢?另外服务器端到底怎么来控制?

#6


引用楼主 qqaoshi888 的回复:
二、客户端也有自己的监听端口,服务器把处理结果发送至该端口,客户端收到这个数据时怎么去和前期的那个请求命令进行关联处理

我认为是,客户端的与请求命令的关联一般好处理,多半是单一命令,或者数个命令。
而困难的恰恰是服务器端,服务器可能同时对多客户提供服务,那么就应该建立一个命令表,对应到各个客户,那些客户的命令还在队列中,那些是正在处理中的命令。那些命令被处理完了,需要返回相应信息到对应客户。
在我的系统中,这个命令表,及服务器提供的常用服务定义,可以看成时连接业务逻辑层和底层网络传输层的纽带,2个层通过这个来交互。

#7


引用楼主 qqaoshi888 的回复:
一、使用已经建立的客户端的socket发送,客户端如何知道服务器已经把数据返回了;

这个一般可以通过你定义的协议包来判断,判断服务器数据返回,数据完整性的。如果没有返回,那客户端应该定义超时处理请求机制,必要的数据在保证网络无故障的情况下,可以考虑重发等其他方式。

#8


说说我的想法:
1.如果你这样分层的话 客户端假如有数据存储的话应该放在哪呢 比如XML文档或是其他一些形式的存储
2.服务器端这样分 直观上看是一种串联的形式 也就是有了你的想法(控制和传输谁先谁后的问题) 如果把通讯层分离开来呢 他和服务器形成一种并联的形式 把通讯抽出来作为一个子系统

#9


引用 7 楼 yyd021 的回复:
引用楼主 qqaoshi888 的回复:
一、使用已经建立的客户端的socket发送,客户端如何知道服务器已经把数据返回了;

这个一般可以通过你定义的协议包来判断,判断服务器数据返回,数据完整性的。如果没有返回,那客户端应该定义超时处理请求机制,必要的数据在保证网络无故障的情况下,可以考虑重发等其他方式。

谢谢您的指导。我的意图好像没有阐述清楚,下面我就说个例子吧:
客户端调用  Dataset GetUserList() 获取用户列表,该函数里面会创建一个socket,然后使用networkstream写入要查询的命令及内容,服务器收到后把执行结果再通过networkstream写入执行结果。我的疑问是客户端的socket的发送是由程序员控制的,但是怎么样通过该networkstream自动获得服务器的执行结果呢?

#10


如果数据传输的性能要求不是很高,数据的传输可以考虑使用WCF,比直接使用socket应该容易多了。

#11


上面是以前同事的建议

#12


引用 10 楼 yishanhai 的回复:
如果数据传输的性能要求不是很高,数据的传输可以考虑使用WCF,比直接使用socket应该容易多了。

我用的.NET 2.0 ,WCF需要使用3.0

#13


你要直接基于Socket编程的话,发送数据必须写Sokcet的Send或BeginSend命令。
要接收数据的话,同样服务器端必须Receive或BeginReceive命令。
你可以在DataSet类中添加一个事件,处理接收到服务器返回的结果。