Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Socket.Receive()停止接收,窗口大小减小为零_C#_Sockets - Fatal编程技术网

C# Socket.Receive()停止接收,窗口大小减小为零

C# Socket.Receive()停止接收,窗口大小减小为零,c#,sockets,C#,Sockets,我有一个tcp连接和两个线程分别处理发送和接收。有时,接收线程在程序启动几分钟后无法接收任何数据,然后从receive()方法获得超时错误。但是Wireshark向我显示了线路上有数据,由于程序停止接收,接收窗口的大小减小到零 似乎这种情况在我的笔记本电脑上更为频繁,这是一台在MacOSX上并行运行的Windows7 class Test { public static string Host { get; set; } public static int Port { get;

我有一个tcp连接和两个线程分别处理发送和接收。有时,接收线程在程序启动几分钟后无法接收任何数据,然后从receive()方法获得超时错误。但是Wireshark向我显示了线路上有数据,由于程序停止接收,接收窗口的大小减小到零

似乎这种情况在我的笔记本电脑上更为频繁,这是一台在MacOSX上并行运行的Windows7

class Test
{
    public static string Host { get; set; }
    public static int Port { get; set; }
    public static Action<Exception> ErrorHandler { get; set; }

    private Socket socket;
    private object sendSync;

    private Thread recvThread;
    private Thread sendThread;
    private Thread connectThread;

    private readonly int RECEIVETIMOUT = 20 * 1000;
    private readonly int MAXCONNECTATTEMPTINTERVAL = 27;

    private int connectingAttempt = 0;

    private ManualResetEvent sendReadyEvent;
    private ManualResetEvent receiveReadyEvent;
    private ManualResetEvent sendStoppedEvent;
    private ManualResetEvent receiveStoppedEvent;


    private Queue<byte[]> waitingRequests;

    private Test()
    {
        sendSync = new object();
        waitingRequests = new Queue<byte[]>();

        sendReadyEvent = new ManualResetEvent(false);
        receiveReadyEvent = new ManualResetEvent(false);

        sendStoppedEvent = new ManualResetEvent(true);
        receiveStoppedEvent = new ManualResetEvent(true);

        sendThread = new Thread(this.Send);
        sendThread.IsBackground = true;
        sendThread.Start();

        recvThread = new Thread(this.Receive);
        recvThread.IsBackground = true;
        recvThread.Start();

        connectThread = new Thread(this.Connect);
        connectThread.IsBackground = true;
        connectThread.Start();

        callbackThread = new Thread(this.callback);
        callbackThread.IsBackground = true;
        callbackThread.Start();
    }

    private static Test instance = null;
    public static Test GetInstance()
    {
        if(instance == null)
            instance = new Test();
        return instance;
    }

    private void Connect()
    {
        while (true)
        {
            try
            {
                sendStoppedEvent.WaitOne();
                receiveStoppedEvent.WaitOne();

                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.ReceiveTimeout = RECEIVETIMOUT;

                var ip = Dns.GetHostAddresses(Host)[0];
                var endPoint = new IPEndPoint(ip, Port);
                socket.Connect(endPoint);

                sendStoppedEvent.Reset();
                receiveStoppedEvent.Reset();

                startSend();
                startReceive();
            }
            catch (SocketException e)
            {
                var waitSecond = (int)Math.Pow(3, connectingAttempt);
                if (waitSecond >= MAXCONNECTATTEMPTINTERVAL)
                {
                    waitSecond = MAXCONNECTATTEMPTINTERVAL;
                    if(ErrorHandler !=null)
                        ErrorHandler(e);
                }

                Thread.Sleep(waitSecond * 1000);
                connectingAttempt++;
            }
        }
    }

    public void Send(byte[] request)
    {
        lock (sendSync)
        {
            waitingRequests.Enqueue(request);
            Monitor.Pulse(sendSync);
        }
    }

    private void Send()
    {
        while (true)
        {
            sendReadyEvent.WaitOne();
            byte[] bytes;
            lock (sendSync)
            {
                if (waitingRequests.Count == 0)
                    Monitor.Wait(sendSync)
                bytes = waitingRequests.Dequeue();
            }

            int i = 0;
            while (i < bytes.Length)
            {
                try
                {
                    i += socket.Send(bytes, i, bytes.Length - i, SocketFlags.None);
                }
                catch (SocketException e)
                {
                    stopSend();
                    break;
                }
                catch (ObjectDisposedException e)
                {
                    stopSend();
                    break;
                }
            }
        }
    }

    private void stopSend()
    {
        socket.Close();
        sendReadyEvent.Reset();
        sendStoppedEvent.Set();
    }

    private void startSend()
    {
        sendReadyEvent.Set();
    }

    private int totalReceived = 0;
    private int  recevied = 0;

    private void Receive()
    {
        int RECVBUFFERSIZE = 1024 * 1024 * 2;
        byte[] recvBuffer = new byte[RECVBUFFERSIZE];
        while (true)
        {
            receiveReadyEvent.WaitOne();
            try
            {
                recevied = socket.Receive(recvBuffer, totalReceived, 1024, SocketFlags.None);
                if (recevied == 0)
                    stopReceive();
                totalReceived += recevied;
                //parse data
                ......
            }
            catch (SocketException e)
            {
                stopReceive();
            }
            catch (ObjectDisposedException e)
            {
                stopReceive();
            }
        }
    }

    private void stopReceive()
    {
        totalReceived = 0;
        recevied = 0;

        socket.Close();
        receiveReadyEvent.Reset();
        receiveStoppedEvent.Set();
    }

    private void startReceive()
    {
        receiveReadyEvent.Set();
    }
}
类测试
{
公共静态字符串主机{get;set;}
公共静态int端口{get;set;}
公共静态操作错误处理程序{get;set;}
专用插座;
私有对象发送同步;
私有线程recvThread;
私有线程发送线程;
私有线程连接线程;
私有只读int RECEIVETIMOUT=20*1000;
私有只读int MAXCONNECTATTEMPTINTERVAL=27;
私有int-connectingAttempt=0;
私人手册重置事件sendReadyEvent;
私人手册重置事件接收人事件;
私人手册重置事件sendStoppedEvent;
私人手册重置事件接收停止事件;
私有队列等待请求;
私人测试()
{
sendSync=新对象();
waitingRequests=新队列();
sendReadyEvent=新手动重置事件(错误);
receiveReadyEvent=新手动重置事件(假);
sendStoppedEvent=新手动重置事件(真);
receiveStoppedEvent=新手动重置事件(真);
sendThread=新线程(this.Send);
sendThread.IsBackground=true;
sendThread.Start();
recvThread=新线程(this.Receive);
recvThread.IsBackground=true;
recvThread.Start();
connectThread=新线程(this.Connect);
connectThread.IsBackground=true;
connectThread.Start();
callbackThread=新线程(this.callback);
callbackThread.IsBackground=true;
callbackThread.Start();
}
私有静态测试实例=null;
公共静态测试GetInstance()
{
if(实例==null)
实例=新测试();
返回实例;
}
专用void Connect()
{
while(true)
{
尝试
{
sendstoppedeEvent.WaitOne();
receivestoppedeEvent.WaitOne();
套接字=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
socket.ReceiveTimeout=ReceiveTimeout;
var ip=Dns.GetHostAddresses(主机)[0];
var端点=新的IPEndPoint(ip,端口);
socket.Connect(端点);
sendstoppedeEvent.Reset();
receiveStoppedEvent.Reset();
startSend();
startReceive();
}
捕获(SocketException e)
{
var waitSecond=(int)Math.Pow(3,connectingAttempt);
如果(waitSecond>=MAXCONNECTATTEMPTINTERVAL)
{
waitSecond=MAXCONNECTATTEMPTINTERVAL;
if(ErrorHandler!=null)
错误处理程序(e);
}
线程睡眠(等待秒*1000);
connectingAttempt++;
}
}
}
公共无效发送(字节[]请求)
{
锁定(发送同步)
{
等待请求。排队(请求);
监视脉冲(sendSync);
}
}
私有无效发送()
{
while(true)
{
sendReadyEvent.WaitOne();
字节[]字节;
锁定(发送同步)
{
if(waitingRequests.Count==0)
监视器。等待(sendSync)
字节=waitingRequests.Dequeue();
}
int i=0;
while(i
这是Wireshark垃圾场

否。时间源目标协议长度信息

4850 1971.053146客户端服务器TCP 90 netview-aix-3>autodesk nlm[PSH,ACK]Seq=7969 ACK=188674 Win=232 Len=36

No.时间源目标协议长度