Здесь курят мануал.

Добро пожаловать на Пыху!

Логин:
Пароль:
 

Нет прописки? Зарегистрируйся!

Новости

Пыха информатор 3.1
Еще более удобное оповещение о флуде!

Краснодарское время: 24 Май, 2012, 06:46:11

Страниц: [1] 2 3
Печать
Автор Тема: C# №3: Работа с сетью. Sockets.  (Прочитано 17740 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Frozzeg    ↓ 
16 Август, 2009, 01:32:03
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 92
Сообщений: 5497
Сила слова: 1.67

Сегодня я расскажу о работе с сокетами на примере клиент-сервера, а если быть точнее - мы будем делать онлайн-рисовалку, т.е. в режиме реального времени мы будем рисовать и это будут видеть другие пользователи.
 
http://frozzeg.no-ip.info/screens/screen_183_351940399.jpg
 
Задача сервера: принимать входящие соединения и пакеты (координаты точки, в которой нужно рисовать) от клиентов и разсылать эти координаты всем клиентам, подключенным к серверу.
Задача клиента: при попытке что либо нарисовать, сначала отправляем данные серверу, затем, если отправка прошла успешно - принимать координаты и нарисовать в указанном месте черную точку.
 

 
Написание сервера.
 
Подключаем нужные библиотеки
C#
using System.Net;
using System.Net.Sockets;
using System.Threading;

Инициализация переменных
C#

        // Здесь будет хранится статус сервера
        bool isServerRunning;
        // Здесь будет список наших клиентов
        private Hashtable clients;
        // Это сокет нашего сервера
        Socket listener;
        // Порт, на котором будем прослушивать входящие соединения
        int port = 1991;
        // Точка для прослушки входящих соединений (состоит из адреса и порта)
        IPEndPoint Point;
        // Список потоков
        private List<Thread> threads = new List<Thread>();

ЗНачинаем слушать входящие соединения
C#
private void ServerStart()
        {
            clients = new Hashtable(30);
            isServerRunning = true;
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // Определяем конечную точку, IPAddress.Any означает что наш сервер будет принимать входящие соединения с любых адресов
            Point = new IPEndPoint(IPAddress.Any, port);
            // Связываем сокет с конечной точкой
            listener.Bind(Point);
            // Начинаем слушать входящие соединения
            listener.Listen(10);
 
            SocketAccepter();
        }

Обрабатываем входящие соединения
C#
private void SocketAccepter()
        {
            // Запускаем цикл в отдельном потоке, чтобы приложение не зависло
            Thread th = new Thread(delegate()
                {
                    while (isServerRunning)
                    {
                        // Создаем новый сокет, по которому мы сможем обращаться клиенту
                        // Этот цикл остановится, пока какой-нибудь клиент не попытается присоединиться к серверу
                        Socket client = listener.Accept();
                        // Теперь, обратившись к объекту client, мы сможем отсылать и принимать пакеты от последнего подключившегося пользователя.
                        // Добавляем подключенного клиента в список всех клиентов, для дальнейшей массовой рассылки пакетов
                        clients.Add(client, "");
                        // Начинаем принимать входящие пакеты
                        Thread thh = new Thread(delegate()
                                                       {
                                                           MessageReceiver(client);
                                                       });
                        thh.Start();
                    }
                });
            // Приведенный выше цикл пока что не работает, запускаем поток. Теперь цикл работает.
            th.Start();
            threads.Add(th);
        }

Метод приема пакетов
C#
private void MessageReceiver(Socket r_client)
        {
            // Для каждого нового подключения, будет создан свой поток для приема пакетов
            Thread th = new Thread(delegate()
                {
                    while (isServerRunning)
                    {
                        try
                        {
                                // Сюда будем записывать принятые байты
                                byte[] bytes = new byte[1024];
                                // Принимаем
                                r_client.Receive(bytes);
                                if (bytes.Length != 0)
                                {
                                    // Отсылаем принятый пакет от клиента всем клиентам
                                    foreach (Socket s_client in clients.Keys)
                                    {
                                        MessageSender(s_client, bytes);
                                    }
                                }
                        }
                        catch {}
                    }
                });
            th.Start();
            threads.Add(th);
        }

Метод отправки пакетов
C#

        private void MessageSender(Socket c_client, byte[] bytes)
        {
            try
            {
                // Отправляем пакет
                c_client.Send(bytes);
 
            }
            catch {}
        }

 

Написание клиента.
 
Подключаем библиотеки
C#
using System.Net;
using System.Net.Sockets;
using System.Threading;

Инициализация переменных
C#
// Разрешено ли рисовать (т.е. если движение мыши осуществляется при нажатой клавише)
        private bool canDraw;
        // Статус клиента
        private bool client_running;
        // Сокет клиента
        private Socket client;
        // Адрес сервера
        private IPAddress ip = IPAddress.Parse("127.0.0.1");
        // Порт, по которому будем присоединяться
        private int port = 1991;
        // Список потоков
        private List<Thread> threads = new List<Thread>();

Коннект к серверу
C#
void Connect()
        {
            try
            {
                client_running = true;
                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                client.Connect(ip, port);
                Receiver();
            }
            catch { }
        }

Метод, принимающий данные от сервера
C#
void Receiver()
        {
            Thread th = new Thread(delegate()
                                       {
                                           while (client_running)
                                           {
                                               try
                                               {
                                                   byte[] bytes = new byte[1024];
                                                   // Принимает данные от сервера в формате "X|Y"
                                                   client.Receive(bytes);
                                                   if (bytes.Length != 0)
                                                   {
                                                       string data = Encoding.UTF8.GetString(bytes);
                                                       string[] split_data = data.Split(new Char[] {'|'});
                                                       // Передаем отпарсенные значения методу Draw на отрисовку
                                                       Draw(Convert.ToInt32(split_data[0]),
                                                            Convert.ToInt32(split_data[1]));
                                                   }
                                               }
                                               catch {}
                                           }
                                       });
            th.Start();
            threads.Add(th);
        }

Метод для отправки пакетов серверу
C#
void Sender(string msg)
        {
            try
            {
                byte[] bytes = new byte[1024];
                bytes = Encoding.UTF8.GetBytes(msg);
                client.Send(bytes);
            }
            catch {}
        }

Метод рисования
C#
void Draw(int x, int y)
        {
            try
            {
                Graphics graphics = CreateGraphics();
                graphics.FillEllipse(new SolidBrush(Color.Black), x, y, 5, 5);
            }
            catch {}
        }

Остались пара событий, тут я думаю все итак понятно
C#
private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            canDraw = true;
        }
 
        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            canDraw = false;
        }
 
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (canDraw)
            {
                string asd = e.X.ToString() + "|" + e.Y.ToString();
                // Посылаем данные серверу (координаты)
                Sender(asd);
            }
        }

* ButtonOnlineServer.rar (73.64 Кб - загружено 533 раз.)
* OnlinePainting.rar (73.43 Кб - загружено 505 раз.)
« Последнее редактирование: 16 Август, 2009, 01:32:03 от Frozzeg » Записан

Эксперт — это человек, который в узкой области допустил все возможные ошибки. © Нильс Бор.
Отложить на завтра — значит впасть в рекурсию. © Frozzeg
phpdude    ↓ 
11 Июль, 2009, 03:05:56 , спустя
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 344
Сообщений: 20781
Сила слова: 1.66

ужасть))
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
rider-sx    ↓ 
11 Июль, 2009, 03:11:22 , спустя 5 минут 26 секунд
НЕ ХУЕТА! ХУЕТА!

drmmmmmm
Группа: Адекваты

Карма: 32
Сообщений: 2718
Сила слова: 1.18

http://ridersx.no-ip.biz/scr/server.JPG
Проблемка...
Записан

Frozzeg    ↓ 
11 Июль, 2009, 03:21:37 , спустя 10 минут 15 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 92
Сообщений: 5497
Сила слова: 1.67


ужасть))
ага, просто показал сам принцип работы

http://ridersx.no-ip.biz/scr/server.JPG
Проблемка...
поставь везде в коде try catch блоки
Записан

Эксперт — это человек, который в узкой области допустил все возможные ошибки. © Нильс Бор.
Отложить на завтра — значит впасть в рекурсию. © Frozzeg
phpdude    ↓ 
11 Июль, 2009, 03:22:07 , спустя 30 секунд
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 344
Сообщений: 20781
Сила слова: 1.66


http://ridersx.no-ip.biz/scr/server.JPG
Проблемка...
нажми дебаг а не билд и посмотри чо получится :)
Спустя 21 секунду добавил
f5, ане сеrl + f5
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Frozzeg    ↓ 
11 Июль, 2009, 03:25:49 , спустя 3 минуты 42 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 92
Сообщений: 5497
Сила слова: 1.67

или так) кстати - вечная проблема
у меня всегда все работает, а когда кому-нить кидаешь вечно приходится баги исправлять
Записан

Эксперт — это человек, который в узкой области допустил все возможные ошибки. © Нильс Бор.
Отложить на завтра — значит впасть в рекурсию. © Frozzeg
rider-sx    ↓ 
11 Июль, 2009, 03:29:45 , спустя 3 минуты 56 секунд
НЕ ХУЕТА! ХУЕТА!

drmmmmmm
Группа: Адекваты

Карма: 32
Сообщений: 2718
Сила слова: 1.18

Странно... но при дебаге говорит что все нормульно все работает... а контрл+ф5 жму вылезает ошибка...
Frozzeg, Я нуб, совсем нуб в этом вопросе, так что не понял я что и куда вставлять )
Спустя 1 минуту 40 секунд добавил
попробовал запустить все это дело из скачанных примеров, запустил сервер, потом 2 клиента, в одном рисую все рисуется появдяется, но во 2 клиенте нет =) Может поправить ччего надобно ? м?
Записан

Frozzeg    ↓ 
11 Июль, 2009, 03:30:19 , спустя 34 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 92
Сообщений: 5497
Сила слова: 1.67

Хм, попробуй зайти в Меню - Build - Cinfguration Manager - Configuration и поставь там Release
Записан

Эксперт — это человек, который в узкой области допустил все возможные ошибки. © Нильс Бор.
Отложить на завтра — значит впасть в рекурсию. © Frozzeg
phpdude    ↓ 
11 Июль, 2009, 03:33:44 , спустя 3 минуты 25 секунд
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 344
Сообщений: д-о-х-у-я!
Сила слова: 1.66


Хм, попробуй зайти в Меню - Build - Cinfguration Manager - Configuration и поставь там Release
думаю что проблема с тредингом.
 
во вторых - прикольная технология взаимодействия .net => .net = Remoting. есть чо рассказать по ней?
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Frozzeg    ↓ 
11 Июль, 2009, 03:40:37 , спустя 6 минут 53 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 92
Сообщений: 5497
Сила слова: 1.67

rider-sx, Попробуй написать заного все самому, опираясь на мой код и документацию по используемым классам
Спустя 1 минуту 22 секунды добавил


Хм, попробуй зайти в Меню - Build - Cinfguration Manager - Configuration и поставь там Release
думаю что проблема с тредингом.
 
во вторых - прикольная технология взаимодействия .net => .net = Remoting. есть чо рассказать по ней?
не юзал никогда
Спустя 4 минуты 18 секунд добавил
rider-sx, обновил исходники, попробуй щас
Записан

Эксперт — это человек, который в узкой области допустил все возможные ошибки. © Нильс Бор.
Отложить на завтра — значит впасть в рекурсию. © Frozzeg
rider-sx    ↓ 
11 Июль, 2009, 05:19:33 , спустя 1 час 38 минут 56 секунд
НЕ ХУЕТА! ХУЕТА!

drmmmmmm
Группа: Адекваты

Карма: 32
Сообщений: 2718
Сила слова: 1.18

Frozzeg, щас попробую
Спустя 12 минут 28 секунд добавил
Во! Айс ))) Все гут и работает ) Спасибо ;)
Спустя 15 минут 11 секунд добавил
Это наверно не столь важно но все же ))) http://ridersx.no-ip.biz/scr/format.JPG
Я так понял что данные не в той форме принимаются которая нужна методу Draw?
Спустя 3 минуты 46 секунд добавил
Frozzeg, Еще можешь выложить инсталятор XNA Game Studio на своем серве, а то винду переустанавливать как то не прет ;)
« Последнее редактирование: 11 Июль, 2009, 05:19:33 от rider-sx » Записан

Frozzeg    ↓ 
11 Июль, 2009, 05:47:57 , спустя 28 минут 24 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 92
Сообщений: 5497
Сила слова: 1.67

данные для всех форм одни и те же, щас выложу
Спустя 3 минуты 17 секунд добавил
http://frozzeg.no-ip.info/XNAGS30_setup.rar
Записан

Эксперт — это человек, который в узкой области допустил все возможные ошибки. © Нильс Бор.
Отложить на завтра — значит впасть в рекурсию. © Frozzeg
rider-sx    ↓ 
11 Июль, 2009, 06:00:55 , спустя 12 минут 58 секунд
НЕ ХУЕТА! ХУЕТА!

drmmmmmm
Группа: Адекваты

Карма: 32
Сообщений: 2718
Сила слова: 1.18

Frozzeg, спасибо =) скачаю попробую чтонить по туторам на их сайте заделать )
Записан

Frozzeg    ↓ 
11 Июль, 2009, 06:10:21 , спустя 9 минут 26 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Санитары

Карма: 92
Сообщений: 5497
Сила слова: 1.67

рановато ты за ХНА взялся, сначало изучи специфику языка
 
з.ы. http://xnadev.ru/news.php
Записан

Эксперт — это человек, который в узкой области допустил все возможные ошибки. © Нильс Бор.
Отложить на завтра — значит впасть в рекурсию. © Frozzeg
rider-sx    ↓ 
11 Июль, 2009, 06:13:27 , спустя 3 минуты 6 секунд
НЕ ХУЕТА! ХУЕТА!

drmmmmmm
Группа: Адекваты

Карма: 32
Сообщений: 2718
Сила слова: 1.18


рановато ты за ХНА взялся, сначало изучи специфику языка
 
з.ы. http://xnadev.ru/news.php
Возможно =) Ну по крайней мере мне вполне понятны туторы на которые там )
Записан

Страниц: [1] 2 3
Печать
 

Перейти в:  

Этот топик скрыли: NRG, adw0rd, Status