小编Gre*_*jda的帖子

当超时设置为无限时,为什么Socket.Receive会在半封闭连接上超时?

下面是一个C#程序,演示了这个问题.

服务器开始侦听套接字.客户端连接到服务器,发送消息,使用Shutdown(SocketShutdown.Send)关闭其发送的一半连接,让服务器知道消息的结束位置,并等待服务器的响应.服务器读取消息,进行一些冗长的计算(这里使用睡眠调用进行模拟),向客户端发送消息,然后关闭连接.

在Windows上,客户端的接收呼叫总是在2分钟后失败,因为"连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机未能响应",即使超时是设置为无限.

如果我使用Mono在Linux中运行该程序,即使我将"冗长操作"设置为10分钟也不会发生超时,但是无论是使用Mono还是.NET运行它都会在Windows中发生.如果我将超时设置为1秒,则在1秒后超时.换句话说,它在我设置的超时或2分钟内超时,以较小者为准.

一个类似的示例程序,服务器向客户端发送消息,没有从客户端到服务器的消息,也没有半关闭,按预期工作,没有超时.

我可以通过修改我的协议来解决这个问题,以便在消息完成时使用其他一些指示服务器的方法(可能在消息前面加上消息的长度).但我想知道这里发生了什么.当超时设置为无限时,为什么Socket.Receive会在半闭连接上超时?

根据我的理解,只有半封闭发送的连接应该能够无限期地继续接收数据.在Windows的这个基本部分中似乎不太可能存在错误.难道我做错了什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            // Start server thread
            Thread serverThread = new Thread(ServerStart);
            serverThread.IsBackground = true;
            serverThread.Start();

            // Give the server some time to start listening
            Thread.Sleep(2000);

            ClientStart();
        }

        static int PortNumber = 8181;

        static void ServerStart()
        {
            TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Any, PortNumber));
            listener.Start();
            while (true) …
Run Code Online (Sandbox Code Playgroud)

c# sockets winsock

6
推荐指数
1
解决办法
3175
查看次数

标签 统计

c# ×1

sockets ×1

winsock ×1