使用同一个TCP客户端进行读写并保持连接活动

4
我有以下情况:
客户端->路由器->互联网->专用服务器

客户端:启动时连接到服务器并保持连接。偶尔会收到来自服务器的文件更改通知。开始同步进程,之后通知服务器是否成功。有时可能会失去连接,因此需要重新建立新连接。

服务器(互联网):包含有时更改的文件。接受传入的客户端,并保留该客户端的tcpclient对象。它永远不能直接与客户端连接,因为客户端位于多个路由器后面;这就是保持连接的原因。当进行更改时,通知客户端,并为每个客户端检查同步成功消息。

问题:

  1. 如何在客户端和服务器端有效地保持连接?

  2. 当客户端想要通知服务器同步过程成功完成,但同时服务器通知客户端有一个新的更新时会发生什么?

  3. 只创建Tcpclient(客户端)并在整个程序中保持此对象是否是一种好的做法?当某些网络操作失败时,尝试再次使用此tcpclient对象连接是否可行?

我做了很多研究,但实际上找不到一些保持使用相同tcpclient的东西。

顺便说一句:这是一个基于我的先前帖子的新线程,在那里提出了此解决方案(重用tcpclient)(udp packet not coming through

问候 Daan,并感谢您的关注。

3个回答

6
我该如何在客户端和服务器端有效地保持连接?
如果您激活SO_KEEPALIVE,TCP可以默认发送keep alive消息。但是,发送自己的keep alive消息可能是个好主意(以防止路由器等设备断开空闲连接)。
当客户端想要通知服务器同步过程成功时,同时服务器又通知客户端有新更新时会发生什么?
设计您的协议,使其具有请求ID并能区分通知和回复。
将API设计为同步,但使用异步套接字处理。
只创建一个Tcpclient(客户端)并在整个程序中保留此对象,这是一种好习惯吗?当某些网络操作失败时,再次尝试使用此tcpclient对象连接是否可行?
您确定可以再次使用同一客户端进行连接吗?据我所知,Socket不支持,TcpClient也应该是如此。
只要客户端没有断开连接,我会继续使用同一客户端。

如果您参考SO_KEEPALIVE套接字选项,它默认情况下是未启用的。如果启用,则默认超时通常为每两个小时发送一条保持活动消息。TCP没有其他保持活动机制。 - Some programmer dude
@JoachimPileborg:谢谢。我以为它默认是开启的。 - jgauffin
那么...你如何激活该套接字选项? - Nyerguds
1
socket.SetSocketOption(SocketOptionLevel.Tcp,SocketOptionName.KeepAlive,1); - jgauffin

3
为了保持连接的开放,确保客户端与服务器之间没有网络故障,您可以在协议中添加两个消息:Keep-alive 和 keep-alive-reply。客户端或服务器(由您决定)会定期发送 keep-alive 消息(例如每分钟一次),另一端回复一个 keep-alive-reply。如果发送 keep-alive 消息的一方在发送下一条 keep-alive 消息时没有收到回复,则可以将连接视为无效并关闭该连接。另一端需要一个计时器来发送回复。如果在指定时间内未收到 keep-alive 请求,则应关闭连接。
客户端只需让服务器的通知排队,并在可能的情况下处理它们。您可以增加客户端的接收缓冲区(使用 setsockopt 和 SO_RCVBUF),或者保留自己的队列。为了跟踪“sync-done”消息与“do-sync”消息,您必须向消息添加某种消息标识符。这可以是简单的整数值,从零开始,然后服务器为每个“do-sync”消息递增它。
只要有一个可用的连接对象,请保留该连接对象。当重新连接时,请创建一个新的连接对象,以确保安全。但是如果重用旧连接对象,则可能也能工作,我不太了解 C#和 .NET 库。

0

嗨,Daan。这个问题已经在networkComms.net的最新提交中得到解决。如果它检测到没有其他流量被发送,它会每隔几秒钟发送一个单字节来保持连接活动状态。如果您查看这个开源的C#网络通信库,从这里的第11行示例开始,您可能比自己从头开始创建一切更快地启动和运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接