Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?
Такі:
byte[] hash=new byte[2]; hash ^= new byte[] {data[i], data[i + 1]};
шо ж ви такий неуважний, я ж там нижче написав
а воно каже, шо не мона зробити ^ між масивами байт
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → C#, .NET → Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?
Такі:
byte[] hash=new byte[2]; hash ^= new byte[] {data[i], data[i + 1]};
шо ж ви такий неуважний, я ж там нижче написав
а воно каже, шо не мона зробити ^ між масивами байт
Так, дійсно.
отак зробив
static ushort GetHash(byte[] data)
{
int lenght = data.Length;
byte[] buff;
if (lenght%2 == 1)
{
buff = new byte[lenght + 1];
Array.Copy(data,buff,lenght);
buff[lenght] = 0;
}
else
{
buff = data;
}
ushort hash = 0;
for (int i = 0; i < lenght; i+=2)
{
hash ^= (ushort)BitConverter.ToInt16(buff, i);
}
return hash;
}
У мене трохи фобія на такі конструкції. Ви двічі копіюєте масив (гаразд, один чи два рази, залежно від парності) - а це довго.
У мене трохи фобія на такі конструкції. Ви двічі копіюєте масив (гаразд, один чи два рази, залежно від парності) - а це довго.
ну там же або 1 або 0, це ж типу клас, тому buff буде просто посилатись на data, чи нє?
аа, нє, ступив, ну то й шо з того
Хм, хіба в .Net нема стандартного CRC32?
Хм, хіба в .Net нема стандартного CRC32?
я шось шукав шукав, але не знайшов
блііін, я так втомився з цим UDP, я прям аж розізлився. Дивіться, запускаю сервер, запускаю клієнт, і перше відправлене повідомлення сервер приймає нормально, але як тільки сервер намагається запустити другий раз метод BeginReceiveFrom - то вилазить виключення - "Удаленный хост принудительно разорвал существующее подключение", яке в срау підключення, якщо UDP працює без підключення???
код серверу
public class Server
{
private string host = "127.0.0.1";
private static int portReceive = 9060;
private static int portSend = 9061;
private Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private byte[] buffer = new byte[1024];
public List<ClientData> clientDatas = new List<ClientData>();
private static IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, portReceive);
private EndPoint endPointReceive = (EndPoint)ipEndPoint;
private static IPEndPoint ipEndPoint1 = new IPEndPoint(IPAddress.Any, portSend);
private EndPoint endPointSend = (EndPoint)ipEndPoint1;
public void Start()
{
socket.Bind(endPointReceive);
ClientData data = new ClientData();
data.endPointReceive = new IPEndPoint(0,0);
data.endPointSend = endPointSend;
data.Socket = socket;
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref data.endPointReceive, new AsyncCallback(ReceiveCallback), data);
}
private void ReceiveCallback(IAsyncResult ar)
{
ClientData data = (ClientData)ar.AsyncState;
int n = socket.EndReceiveFrom(ar, ref data.endPointReceive);
data.Socket = socket;
data.endPointSend = new IPEndPoint(((IPEndPoint)data.endPointReceive).Address,portSend);
((IPEndPoint) data.endPointReceive).Port = portReceive;
if (!clientDatas.Contains(data))
{
clientDatas.Add(data);
Console.WriteLine("added client");
}
Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, n));
if (clientDatas.Count > 0)
foreach (var clientData in clientDatas)
{
//if(clientData!=data)
clientData.Socket.SendTo(buffer, 0, n, SocketFlags.None, data.endPointSend);
}
endPointReceive = new IPEndPoint(IPAddress.Any, portReceive);
data.Socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref data.endPointReceive,
new AsyncCallback(ReceiveCallback), data);
}
public class ClientData
{
public EndPoint endPointReceive;
public EndPoint endPointSend;
public int id;
public Socket Socket;
}
}
код клієнту
public static class Client
{
private static string host = "127.0.0.1";
private static int portReceive = 9061, portSend = 9060;
private static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private static byte[] buffer = new byte[1024];
private static IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(host), portSend);
private static EndPoint endPointSend = (EndPoint)ipEndPoint;
public static EndPoint endPointReceive = new IPEndPoint(IPAddress.Parse(host), portReceive);
private static bool isConnected = false;
private static int ID;
public static void Start()
{
Send("");
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPointReceive, new AsyncCallback(ReceiveCallback), socket);
}
private static void ReceiveCallback(IAsyncResult ar)
{
int n = socket.EndReceive(ar);
if (n == 4)
{
ID = BitConverter.ToInt32(buffer, 0);
if (ID > 0)
isConnected = true;
}
else if (n > 0)
{
}
Console.WriteLine(n);
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPointReceive, new AsyncCallback(ReceiveCallback), socket);
}
public static void Send(string message)
{
byte[] buffer = Encoding.UTF8.GetBytes(message);
socket.BeginSendTo(buffer, 0, buffer.Length, SocketFlags.None, endPointSend, new AsyncCallback(SendCallback),
socket);
}
private static void SendCallback(IAsyncResult ar)
{
// Socket socket1 = (Socket) ar;
int n = socket.EndSendTo(ar);
}
public static void Connect()
{
string message = "connect";
byte[] buff = Encoding.UTF8.GetBytes(message);
socket.SendTo(buff, 0, buff.Length, SocketFlags.None, endPointSend);
}
/* private static byte[] SetPacket(string data)
{
}*/
}
там є купа незрозумілого коду, котрий нічо не робить, то це я починав робити віртуальне з'єднання чи щось таке, але закинув цю ідею, тому що помилки інші були і т.д....
З брандмауером все гаразд?
З брандмауером все гаразд?
я його вимкнув - перевірив - ввімкнув, так що все ок наче
я вже трохи розібрався і все наче працює, але от знаєте, на TCP сервері, коли підключається новий клієнт, я отримую socket, а потім можу перевірити в колекції клієнтів, якщо там немає такого сокету, то треба додати його тоді, і це файно працює, а от з цими EndPoint'ами так не вийде, вони завжди не рівняються один одному
я вже трохи розібрався і все наче працює, але от знаєте, на TCP сервері, коли підключається новий клієнт, я отримую socket, а потім можу перевірити в колекції клієнтів, якщо там немає такого сокету, то треба додати його тоді, і це файно працює, а от з цими EndPoint'ами так не вийде, вони завжди не рівняються один одному
Можна першим запитом запитати у серверу унікальний ключ (номер), котрий він вишле клієнту, щоб потім додавати в кожне повідомлення. Але є підозра, що так не роблять і є інший механизм виявлення відправника.
koala, можете, будьласка, нагадати, як називається підхід, коли ми додаємо надлишкову інфу щоб мати можливість відновити/виявити помилки? Хочеться згадати університетський курс, але вже навіть забув що вбивати в пошукові системи... >_<
Так і зветься - надлишкова інформація. Можливо, ви за коди Гемінга питаєте?
FakiNyan написав:я вже трохи розібрався і все наче працює, але от знаєте, на TCP сервері, коли підключається новий клієнт, я отримую socket, а потім можу перевірити в колекції клієнтів, якщо там немає такого сокету, то треба додати його тоді, і це файно працює, а от з цими EndPoint'ами так не вийде, вони завжди не рівняються один одному
Можна першим запитом запитати у серверу унікальний ключ (номер), котрий він вишле клієнту, щоб потім додавати в кожне повідомлення. Але є підозра, що так не роблять і є інший механизм виявлення відправника.
koala, можете, будьласка, нагадати, як називається підхід, коли ми додаємо надлишкову інфу щоб мати можливість відновити/виявити помилки? Хочеться згадати університетський курс, але вже навіть забув що вбивати в пошукові системи... >_<
так я це вже давно зробив і все гарно працює
Можливо, ви за коди Гемінга питаєте?
Точно, саме це і цікавило, дякую )
Тааак, хлопці, не знаю, чи писав я це вже, але при виклику BeginReceiveFrom вилазить
Удаленный хост принудительно разорвал существующее подключение
private static string host = "127.0.0.1";
private static int portReceive = 9061, portSend = 9060;
private static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private static byte[] buffer = new byte[1024];
private static IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(host), portSend);
private static EndPoint endPointSend = (EndPoint)ipEndPoint;
public static EndPoint endPointReceive = new IPEndPoint(IPAddress.Parse(host), 0);
private static bool isConnected = false;
private static int ID=0;
public static void Start()
{
Send("");
try
{
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPointReceive, new AsyncCallback(ReceiveCallback), socket);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Є якісь думки з цього приводу?
FakiNyan
Це UDP? Тоді все нормально, бо UDP не створює постійних підключень. Кожний пакет надходить окремо. І мені здається, що Wolf.dp правий, в кожному пакеті мусить бути ідентифікатор клієнта, плюс номер пакету.
Не варто намагатися працювати з цим протоколом як з TCP.
FakiNyan
Це UDP? Тоді все нормально, бо UDP не створює постійних підключень. Кожний пакет надходить окремо. І мені здається, що Wolf.dp правий, в кожному пакеті мусить бути ідентифікатор клієнта, плюс номер пакету.
Не варто намагатися працювати з цим протоколом як з TCP.
да я це все знаю, я передаю ідентифікатор і т.д. І працювати хочу з ним як з UDP, але воно саме по собі працює, як TCP. Тут дивіться, яка штука. Якщо просто почати BeginReceive, то вилазить оцей виняток, котрий тут взагалі непотрібен. Але якщо спочатку зробити Bind, то винятка не буде. Але ж це клієнт. І якщо я запущу два таких клієнти на одному компі, то вилізе інший виняток, який скаже, що не можна два рази Bind'итись до одного й того самого EndPoint'а. Але! Якщо сервер буде ввімкнутим і перед BeginReceive на клієнті я викличу Send, то навіть без Bind'a все буде працювати. А мені потрібно, щоб воно працювало без Bind'a і без попереднього ввімкнення серверу.
Подивився довідку... гм...
public IAsyncResult BeginReceiveFrom(
byte[] buffer,
int offset,
int size,
SocketFlags socketFlags,
ref EndPoint remoteEP,
AsyncCallback callback,
Object state
)
Останній параметр там не сокет.
І зверніть увагу на Socket.BeginReceiveMessageFrom - UDP ж не поток передає, а окремі повідомлення.
Подивився довідку... гм...
public IAsyncResult BeginReceiveFrom( byte[] buffer, int offset, int size, SocketFlags socketFlags, ref EndPoint remoteEP, AsyncCallback callback, Object state )
Останній параметр там не сокет.
І зверніть увагу на Socket.BeginReceiveMessageFrom - UDP ж не поток передає, а окремі повідомлення.
То й шо, що не сокет? Там можна передавати що завгодно, хоч Аллаха. Socket.BeginReceiveMessageFrom нічого не дав, як і раніше вилазить повідомлення - Перед цією операцією треба викликати Bind.