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