Thread udpserver = new Thread
(
delegate()
{
UdpClient udps = new UdpClient(7777);
IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);
while (true)
{
byte[] buffer = udps.Receive(ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buffer.Length, ipe.ToString());
udps.Send(buffer, buffer.Length, ipe);
}
}
);
udpserver.IsBackground = true;
//tcpserver.Start();
udpserver.Start();
byte[] buf=new byte[10];
int sent;
Thread.Sleep(1000);
using (UdpClient udpc = new UdpClient(1111))
{
udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);
for (int i = 0; i < 3; i++)
udpc.Send(buf, buf.Length);
while (udpc.Available > 0)
{
buf = udpc.Receive(ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buf.Length, ipe.ToString());
}
Thread.Sleep(10000);
}
Console.ReadKey();
return;
udpclient разорвано соединение
Код:
если выполнять код пошагово, то все работает как надо, если нет, то выбрасывается исключение на выделенном участе, почему?
может быть недостаточная синхронизация? например Sleep не очень удачно подходит для данной ситуации.
Код:
Thread udpserver = new Thread
(
delegate()
{
UdpClient udps = new UdpClient(7777);
IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);
while (true)
{
byte[] buffer = udps.Receive(ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buffer.Length, ipe.ToString());
udps.Send(buffer, buffer.Length, ipe);
}
}
);
udpserver.IsBackground = true;
//tcpserver.Start();
udpserver.Start();
byte[] buf=new byte[10];
int sent;
using (UdpClient udpc = new UdpClient())
{
udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);
for (int i = 0; i < 3; i++)
udpc.Send(buf, buf.Length);
Thread.Sleep(100);
while (udpc.Available > 0)
{
buf = udpc.Receive(ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buf.Length, ipe.ToString());
}
}
Console.ReadKey();
return;
(
delegate()
{
UdpClient udps = new UdpClient(7777);
IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);
while (true)
{
byte[] buffer = udps.Receive(ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buffer.Length, ipe.ToString());
udps.Send(buffer, buffer.Length, ipe);
}
}
);
udpserver.IsBackground = true;
//tcpserver.Start();
udpserver.Start();
byte[] buf=new byte[10];
int sent;
using (UdpClient udpc = new UdpClient())
{
udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);
for (int i = 0; i < 3; i++)
udpc.Send(buf, buf.Length);
Thread.Sleep(100);
while (udpc.Available > 0)
{
buf = udpc.Receive(ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buf.Length, ipe.ToString());
}
}
Console.ReadKey();
return;
как исправить
[/LEFT]
А приложение само себе будет посылать данные?
сейчас посылает в одном потоке, в другом принимает, а разве есть разница в одном приложении или нет?
а еще сдается мне using тоже виноват. вроде объект уничтожается раньше чем должен. надо еще проверить
Код:
Thread udpserver = new Thread
(
delegate()
{
UdpClient udps = new UdpClient(7777);
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
byte[] buffer = udps.Receive(ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buffer.Length, ipe.ToString());
udps.Send(buffer, buffer.Length, ipe);
}
//Thread.CurrentThread.Abort();
}
);
udpserver.IsBackground = true;
udpserver.Start();
byte[] buf = new byte[10];
using (UdpClient udpc = new UdpClient())
{
udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);
for (int i = 0; i < 3; i++)
{
udpc.Send(buf, buf.Length);
IAsyncResult ReceiveResult = udpc.BeginReceive(
delegate(IAsyncResult ar)
{
buf = udpc.EndReceive(ar, ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buf.Length, ipe.ToString());
}, null);
while (!ReceiveResult.IsCompleted)
{
Application.DoEvents();
Thread.Sleep(50);
}
}
}
Console.ReadKey();
return;
(
delegate()
{
UdpClient udps = new UdpClient(7777);
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
byte[] buffer = udps.Receive(ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buffer.Length, ipe.ToString());
udps.Send(buffer, buffer.Length, ipe);
}
//Thread.CurrentThread.Abort();
}
);
udpserver.IsBackground = true;
udpserver.Start();
byte[] buf = new byte[10];
using (UdpClient udpc = new UdpClient())
{
udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);
for (int i = 0; i < 3; i++)
{
udpc.Send(buf, buf.Length);
IAsyncResult ReceiveResult = udpc.BeginReceive(
delegate(IAsyncResult ar)
{
buf = udpc.EndReceive(ar, ref ipe);
Console.WriteLine("{0} bytes were received from {1}", buf.Length, ipe.ToString());
}, null);
while (!ReceiveResult.IsCompleted)
{
Application.DoEvents();
Thread.Sleep(50);
}
}
}
Console.ReadKey();
return;
то что вы предложили, это же самое, но только создается еще один поток для асинхронного вызова Receive или как оно реализовано в .net я не знаю, раньше создавался только один дополнительные поток для сервера и еще:
while (!ReceiveResult.IsCompleted)
{
Application.DoEvents();
Thread.Sleep(50);
}
имхо это нехорошо дергать поток только для проверки завершенности операции, ведь Receive специально блокирует поток до получения данных
вобщем вот так, это не то что хотелось бы получить
посылаем сразу 3 датаграммы
начинаем слушать. в тот момент, когда сервер получил, обработал и послал обратно, допустим, 2 пакета, и мы читаем данные, но сервер не успел обработать 3 пакет и нам пока больше получать нечего, поэтому поток выполняется дальше, уничтожает объект udpc из-за оператора using а тут сервер наконец обработал 3 часть данных и пытается их выслать, но соединение то закрыто... я вот так понял.
ну или проще если, то udpc.Available может быть 0, хотя данные мы еще не все получили или вообще не получали. вот и весь сказ.
Цитата:
Receive специально блокирует поток
Просто такой цикл позволит обработать очередь сообщений, например. Представьте, что этот код запихнули в метод нажатия кнопки... Пока данные не придут окно "повиснет". Хотя конечно в данном случае наверное и нет смысла делать так. Тем более метод DoEvents в консольном приложении (у меня прога с окошком)
Код:
Thread udpserver = new Thread
(
delegate()
{
UdpClient udps = new UdpClient(new IPEndPoint(IPAddress.Loopback, 7777));
IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);
while (true)
{
byte[] buffer = udps.Receive(ref ipe);
Console.WriteLine("server: {0} bytes were received from {1}", buffer.Length, ipe.ToString());
udps.Send(buffer, buffer.Length, ipe);
}
}
);
udpserver.IsBackground = true;
udpserver.Name = "udpserver";
//tcpserver.Start();
udpserver.Start();
Thread.CurrentThread.Name = "main";
const int size = 1000;
byte[] buf;
int sent;
using (UdpClient udpc = new UdpClient())
{
udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
//udpc.Client.ReceiveBufferSize = 1024 * 1024;
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);
for (int i = 0; i < 3; i++)
{
buf=new byte[size];
buf[0] = (byte)(i + 1);
buf[buf.Length - 1] = (byte)(i + 1);
IAsyncResult iar = udpc.BeginSend(buf, buf.Length,
delegate(IAsyncResult ar)
{
UdpClient udpca = (UdpClient)ar.AsyncState;
Console.WriteLine("client: {0} bytes sent", udpca.EndSend(ar));
},
udpc
);
iar.AsyncWaitHandle.WaitOne();
}
int asd = 3;
while (asd-- > 0)
{
Console.WriteLine(udpc.Available);
buf = udpc.Receive(ref ipe);
Console.WriteLine("client: 0: {2}, l-1:{3}; {0} bytes were received from {1}", buf.Length, ipe.ToString(), buf[0], buf[buf.Length - 1]);
}
}
Console.WriteLine("\npress any key");
Console.ReadKey();
return;
(
delegate()
{
UdpClient udps = new UdpClient(new IPEndPoint(IPAddress.Loopback, 7777));
IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);
while (true)
{
byte[] buffer = udps.Receive(ref ipe);
Console.WriteLine("server: {0} bytes were received from {1}", buffer.Length, ipe.ToString());
udps.Send(buffer, buffer.Length, ipe);
}
}
);
udpserver.IsBackground = true;
udpserver.Name = "udpserver";
//tcpserver.Start();
udpserver.Start();
Thread.CurrentThread.Name = "main";
const int size = 1000;
byte[] buf;
int sent;
using (UdpClient udpc = new UdpClient())
{
udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
//udpc.Client.ReceiveBufferSize = 1024 * 1024;
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);
for (int i = 0; i < 3; i++)
{
buf=new byte[size];
buf[0] = (byte)(i + 1);
buf[buf.Length - 1] = (byte)(i + 1);
IAsyncResult iar = udpc.BeginSend(buf, buf.Length,
delegate(IAsyncResult ar)
{
UdpClient udpca = (UdpClient)ar.AsyncState;
Console.WriteLine("client: {0} bytes sent", udpca.EndSend(ar));
},
udpc
);
iar.AsyncWaitHandle.WaitOne();
}
int asd = 3;
while (asd-- > 0)
{
Console.WriteLine(udpc.Available);
buf = udpc.Receive(ref ipe);
Console.WriteLine("client: 0: {2}, l-1:{3}; {0} bytes were received from {1}", buf.Length, ipe.ToString(), buf[0], buf[buf.Length - 1]);
}
}
Console.WriteLine("\npress any key");
Console.ReadKey();
return;
на выделенном участке было while(udpc.Availabla>0), теперь вот так, и исключения пропали
каким образом udpc.Available влияет на происходящее?
у кого то еще появляются исключения?
соединение и на самом деле "закрывалось" когда использовалось Available, не все пакеты могли отправиться, потому и сокет выбрасывал исключение при попытке прочитать из него