21

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

koala написав:

Такі:

 
byte[] hash=new byte[2];
hash ^= new byte[] {data[i], data[i + 1]};

шо ж ви такий неуважний, я ж там нижче написав

а воно каже, шо не мона зробити ^ між масивами байт

22

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

Так, дійсно.

23

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

отак зробив

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;
        }

24

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

У мене трохи фобія на такі конструкції. Ви двічі копіюєте масив (гаразд, один чи два рази, залежно від парності) - а це довго.

25 Востаннє редагувалося FakiNyan (10.04.2014 16:32:18)

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

koala написав:

У мене трохи фобія на такі конструкції. Ви двічі копіюєте масив (гаразд, один чи два рази, залежно від парності) - а це довго.

ну там же або 1 або 0, це ж типу клас, тому buff буде просто посилатись на data, чи нє?
аа, нє, ступив, ну то й шо з того

26

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

Хм, хіба в .Net нема стандартного CRC32?

27

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

Torbins написав:

Хм, хіба в .Net нема стандартного CRC32?

я шось шукав шукав, але не знайшов

28

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

блііін, я так втомився з цим 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)
         {
            
         }*/
    }

там є купа незрозумілого коду, котрий нічо не робить, то це я починав робити віртуальне з'єднання чи щось таке, але закинув цю ідею, тому що помилки інші були і т.д....

29

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

З брандмауером все гаразд?

30

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

koala написав:

З брандмауером все гаразд?

я його вимкнув - перевірив - ввімкнув, так що все ок наче

31

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

я вже трохи розібрався і все наче працює, але от знаєте, на TCP сервері, коли підключається новий клієнт, я отримую socket, а потім можу перевірити в колекції клієнтів, якщо там немає такого сокету, то треба додати його тоді, і це файно працює, а от з цими EndPoint'ами так не вийде, вони завжди не рівняються один одному

32

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

FakiNyan написав:

я вже трохи розібрався і все наче працює, але от знаєте, на TCP сервері, коли підключається новий клієнт, я отримую socket, а потім можу перевірити в колекції клієнтів, якщо там немає такого сокету, то треба додати його тоді, і це файно працює, а от з цими EndPoint'ами так не вийде, вони завжди не рівняються один одному

Можна першим запитом запитати у серверу унікальний ключ (номер), котрий він вишле клієнту, щоб потім додавати в кожне повідомлення. Але є підозра, що так не роблять і є інший механизм виявлення відправника.

koala, можете, будьласка, нагадати, як називається підхід, коли ми додаємо надлишкову інфу щоб мати можливість відновити/виявити помилки? Хочеться згадати університетський курс, але вже навіть забув що вбивати в пошукові системи... >_<

33

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

Так і зветься - надлишкова інформація. Можливо, ви за коди Гемінга питаєте?

Подякували: Wolf.dp1

34

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

Wolf.dp написав:
FakiNyan написав:

я вже трохи розібрався і все наче працює, але от знаєте, на TCP сервері, коли підключається новий клієнт, я отримую socket, а потім можу перевірити в колекції клієнтів, якщо там немає такого сокету, то треба додати його тоді, і це файно працює, а от з цими EndPoint'ами так не вийде, вони завжди не рівняються один одному

Можна першим запитом запитати у серверу унікальний ключ (номер), котрий він вишле клієнту, щоб потім додавати в кожне повідомлення. Але є підозра, що так не роблять і є інший механизм виявлення відправника.

koala, можете, будьласка, нагадати, як називається підхід, коли ми додаємо надлишкову інфу щоб мати можливість відновити/виявити помилки? Хочеться згадати університетський курс, але вже навіть забув що вбивати в пошукові системи... >_<

так я це вже давно зробив і все гарно працює

35

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

koala написав:

Можливо, ви за коди Гемінга питаєте?

Точно, саме це і цікавило, дякую )

36

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

Тааак, хлопці, не знаю, чи писав я це вже, але при виклику 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);
            }
        }

Є якісь думки з цього приводу?

37 Востаннє редагувалося Torbins (20.04.2014 12:02:10)

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

FakiNyan
Це UDP? Тоді все нормально, бо UDP не створює постійних підключень. Кожний пакет надходить окремо. І мені здається, що Wolf.dp правий, в кожному пакеті мусить бути ідентифікатор клієнта, плюс номер пакету.
Не варто намагатися працювати з цим протоколом як з TCP.

38

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

Torbins написав:

FakiNyan
Це UDP? Тоді все нормально, бо UDP не створює постійних підключень. Кожний пакет надходить окремо. І мені здається, що Wolf.dp правий, в кожному пакеті мусить бути ідентифікатор клієнта, плюс номер пакету.
Не варто намагатися працювати з цим протоколом як з TCP.

да я це все знаю, я передаю ідентифікатор і т.д. І працювати хочу з ним як з UDP, але воно саме по собі працює, як TCP. Тут дивіться, яка штука. Якщо просто почати BeginReceive, то вилазить оцей виняток, котрий тут взагалі непотрібен. Але якщо спочатку зробити Bind, то винятка не буде. Але ж це клієнт. І якщо я запущу два таких клієнти на одному компі, то вилізе інший виняток, який скаже, що не можна два рази Bind'итись до одного й того самого EndPoint'а. Але! Якщо сервер буде ввімкнутим і перед BeginReceive на клієнті я викличу Send, то навіть без Bind'a все буде працювати. А мені потрібно, щоб воно працювало без Bind'a і без попереднього ввімкнення серверу.

39

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

Подивився довідку... гм...

public IAsyncResult BeginReceiveFrom(
    byte[] buffer,
    int offset,
    int size,
    SocketFlags socketFlags,
    ref EndPoint remoteEP,
    AsyncCallback callback,
    Object state
)

Останній параметр там не сокет.
І зверніть увагу на Socket.BeginReceiveMessageFrom - UDP ж не поток передає, а окремі повідомлення.

40

Re: Поясніть за UDP-протокол, як запустити декілька клієнтів на одному ПК?

koala написав:

Подивився довідку... гм...

public IAsyncResult BeginReceiveFrom(
    byte[] buffer,
    int offset,
    int size,
    SocketFlags socketFlags,
    ref EndPoint remoteEP,
    AsyncCallback callback,
    Object state
)

Останній параметр там не сокет.
І зверніть увагу на Socket.BeginReceiveMessageFrom - UDP ж не поток передає, а окремі повідомлення.

То й шо, що не сокет? Там можна передавати що завгодно, хоч Аллаха. Socket.BeginReceiveMessageFrom нічого не дав, як і раніше вилазить повідомлення - Перед цією операцією треба викликати Bind.