结论1:tcpchannel的timeout设置对服务端处理时间过长时是起到超时作用的。
结论2:tcpchannel对连接网络慢或者网络层的执行时间太久是没有起到超时作用的。
结论3:使用新的ClientTransportSink解决了因为网络问题hang太久的问题,
测试一
服务端
class Program


{
static void Main(string[] args)

{
TcpChannel chan = new TcpChannel(8080);
ChannelServices.RegisterChannel(chan,false);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(ServerObject),
"ServerObject", WellKnownObjectMode.Singleton);
Console.WriteLine("server is start");
Console.Read();
chan.StopListening(null);
ChannelServices.UnregisterChannel(chan);
}
}
public class ServerObject : MarshalByRefObject


{
public string SayHello(string name)

{
Thread.Sleep(5000);
return string.Format("Hello {0}", name);
}
}
客户端
class Program


{
static void Main(string[] args)

{
try

{
Hashtable props = new Hashtable();
props["name"] = "tcp_rem";
props["timeout"] = 1000;
TcpChannel _tcpChannel = new TcpChannel(props, null, null);
ChannelServices.RegisterChannel(_tcpChannel, false);
ServerObject so = (ServerObject)Activator.GetObject(typeof(ServerObject), "tcp://127.0.0.1:8080/ServerObject");
Console.WriteLine(so.SayHello("onlytiancai"));
}
catch (Exception ex)

{
Console.WriteLine(ex);
}
Console.Read();
}
}
一秒超时后客户端就会报以下错误
System.Net.Sockets.SocketException: 由于连接方在一段时间后没有正确答复或连接的主
机没有反应,连接尝试失败。
结论:tcpchannel的timeout设置对服务端处理时间过长时是起到超时作用的。
测试二
再做一个测试,把客户端连接的地址改成一个乱七八糟的远程地址。
ServerObject so = (ServerObject)Activator.GetObject(typeof(ServerObject), "tcp://192.192.192.192:8080/ServerObject");
这时候客户端会hang 10秒以上,也有可能hang更久。
结论:tcpchannel对连接网络慢或者网络层的执行时间太久是没有起到超时作用的。
测试三
再做一个测试,把我改进后的TcpClientTransportSink配置上,看看能不能起到超时的作用。
配置文件如下
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application >
<channels>
<channel ref="tcp">
<clientProviders>
<formatter ref="binary"/>
<provider type="WawaSoft.Remoting.Channels.Tcp.TcpClientTransportSinkProvider,WawaRemoting" />
</clientProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
客户端代码如下
class Program


{
static void Main(string[] args)

{
try

{
RemotingConfiguration.Configure("Client.exe.config", false);
ServerObject so = (ServerObject)Activator.GetObject(typeof(ServerObject), "tcp://192.192.192.192:8080/ServerObject");
Console.WriteLine(so.SayHello("onlytiancai"));
}
catch (Exception ex)

{
Console.WriteLine(ex);
}
Console.Read();
}
}
一秒后出现如下错误提示
System.ApplicationException: connect timout
Server stack trace:
在 WawaSoft.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint ipEnd
Point) 位置 E:\huhao\project\RemotingTimeoutTest\WawaRemoting\Channels\RemoteCon
nection.cs:行号 89
结论:使用新的ClientTransportSink解决了因为网络问题hang太久的问题,但是目前的代码我只在connect上加了超时机制,send和receive还没有加超时机制,再有一个问题就是在同步调用上做超时必须另起个线程然后用join做超时,稳定性还得做压力测试来确认。
新的ClientTransportSink和测试代码见以下链接。
RemotingTimeoutTest.zip
以上代码大多都是反射与.net fx,所以稳定性应该还是很好的,只修改了RemoteConnection类的CreateNewSocket方法,如下
修改前
private SocketHandler CreateNewSocket(EndPoint ipEndPoint)

{
Socket socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
this.DisableNagleDelays(socket);
socket.Connect(ipEndPoint);
this._lkgIPEndPoint = socket.RemoteEndPoint;
return this._socketCache.CreateSocketHandler(socket, this._machineAndPort);
}
修改后

private SocketHandler CreateNewSocket(EndPoint ipEndPoint)

{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.Debug, 1);
Exception pingException = null;
DateTime now = DateTime.Now;

System.Threading.Thread pingThread = new System.Threading.Thread(
delegate()

{
try

{
socket.Connect(ipEndPoint);
//这里不用beginConnect,太麻烦
}
catch (Exception ex)

{
pingException = ex;
}
});

pingThread.Start();

if (pingThread.Join(1000))
{
if (pingException == null)

{
return this._socketCache.CreateSocketHandler(socket, this._machineAndPort);
}

else
{throw pingException;}
}
throw new ApplicationException("connect timout");
}
改进;超时的部分想办法不用join事先,用一个waithandle实现。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构