我们已经在IIS 6 / Windows Server 2003下运行了几年的.ashx应用程序。我们最近一直试图让一些新服务器启动并运行,并且需要迁移到Win 2k8 R2和IIS 7.5,但是我有一段时间让应用程序在新服务器上运行良好。
.ashx是我们通过TCP进行会话的自定义消息排队引擎的Web解释器。因此,在.ashx内部,我们创建了一个与消息队列服务器通信的套接字。关于这个体系结构的任何内容都没有改变,但是我在运行.Net 4的Win 2k8和IIS 7.5设置上遇到的错误是
System.Net.Sockets.SocketException(0x80004005):现有的 连接被远程主机强行关闭 System.Net.Sockets.Socket.Receive(Byte [] buffer,SocketFlags 的SocketFlags)
我们不会在较旧的设置上出现此错误 - 相同的代码,尽管它正在运行.Net 3.5运行时。
请记住,这个错误不会从面向HTTP的套接字抛出,而是从尝试与消息队列服务器通信的套接字抛出。我已经通过在Web服务器上运行“原始”telnet会话到消息队列来验证我不相信我有防火墙问题,并且能够成功地与消息队列进行交互。
以下是我们设置套接字的方法:
this.m_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
System.Net.IPAddress ip = System.Net.IPAddress.None;
// Before bothering the DNS server, try to parse numeric IP
try
{
ip = System.Net.IPAddress.Parse(host);
}
catch (FormatException)
{
// Not a numeric IP. Do the DNS lookup.
// (BTW: DNS lookup will convert the IP, but only after a failing lookup, which is slow)
IPHostEntry ipadd = System.Net.Dns.GetHostEntry(host);
// (Note: That lookup might fail. It'll throw a SocketException.)
ip = ipadd.AddressList[0];
}
try
{
this.m_sock.Connect(ip, port);
this.m_sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
this.m_sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.NoDelay, true);
this.m_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);
this.m_sock.ReceiveTimeout = 60 + this.m_timeout;
this.m_sock.Blocking = true;
this.m_sock.ReceiveBufferSize = 65536;
this.m_sock.SendBufferSize = 65536;
if (ok != "" && !this.m_isweb)
{
Console.WriteLine(ok);
}
break;
}
catch (SocketException)
{
this.m_sock.Close();
this.m_sock = null;
}
现在是一个“ReadSome”方法的片段,它在this.m_sock_Receive上爆炸了我们:
if (this.m_sock.Poll(1000000, SelectMode.SelectRead))
{
n = this.m_sock.Available;
if (n == 0)
n = 1; // Presume at least one byte readable
if (max > 0 && n > max)
n = max;
byte[] buf = new byte[n];
int rcvd = this.m_sock.Receive(buf, SocketFlags.None);
if (rcvd == 0)
throw new knetmq_Exception(this, "Read EOF",
knetmq_Exception.codes.EOF);
return buf;
}
在“接收”发生之前,有一个“发送”无异常发生,但是我没有在另一侧看到有效负载。
感谢任何帮助!
答案 0 :(得分:1)
哦,欢乐!我修好了!
缺点:我没有设置我的TTL,并且在新服务器上TTL一直被超过。
更深入:新服务器恰好位于略有不同的网络上。因为我们没有设置TTL,所以TTL默认为1. Wirehark发现TTL被反复超出,因此发出了TCP RST,导致错误被抛出。这就是远程主机永远不会收到消息的原因。
我在这个问题上猛烈抨击了2天,所以我希望最终得到SocketException的人能够看到这个并找到TTL问题!