13 / 13 / 0
Регистрация: 19.07.2012
Сообщений: 14
1

Отправить данные с Сервера на Клиент

28.07.2012, 15:30. Показов 3486. Ответов 0
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Помогите пожалуйста понять как это осуществить в моём примере!!!

В данный момент прохожу стадию обучения творению клиент-серверных приложений на C#
Нашел хороший видео-гайд на ютубе по написанию многопоточного сервера, ну и параллельно пытался понять, что к чему постоянно обращаясь к MSDN

вот листинг с классов сервера(много прокоментил, так как за всем следил через MSDN)

Listener(Ожидание и приём соединение):

Listener.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
namespace lessonMultiServer
{
    class Listener
    {
        Socket s;
        public bool Listening { get; private set; }
        public int  Port      { get; private set; }
 
 
        public Listener(int port)
        {
            Port = port;
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }
 
        // Запускаем
        public void Start()
        {
            // Если уже стартанули то ничего не делаем
            if (Listening) return;
 
            // Стартуем
            // Задаём конечную точку IP и Port
            s.Bind(new IPEndPoint(0, Port));
 
            // Начинаем слушать порт
            // Listen(Максимальная длина очереди ожидающих подключений)
            s.Listen(0);
// Начинает асинхронную операцию, чтобы принять попытку входящего подключения
            s.BeginAccept(callback, null);
            
            // всё стартанули, даём знать об этом классу
            Listening = true;
// Останавливаем
        public void Stop()
        {
            // Если не стартовали то и не останавливаем
            if (!Listening) return;
 
            // Закрываем
            s.Close();
            // Освобождает все ресурсы, используемые текущим экземпляром класса Socket
            s.Dispose();
            // Создаём новый сокет
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }
// Представляет состояние асинхронной операции.
        // Тут всё и случится
        void callback(IAsyncResult ar)
        {
            try
            {
                // Асинхронно принимает входящие попытки подключения и создает 
                // новый объект Socket для связи с удаленным узлом
 
                Socket s = this.s.EndAccept(ar);
 
                // Если создалось подключение с сокетом, то запоминаем сокет
                if (SocketAccepted != null)
                {
                    SocketAccepted(s);
                }
                
                // если нет подключения с сокетом, то пытаемся соединить
                this.s.BeginAccept(callback, null);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        public delegate void SocketAcceptedHandler(Socket e);
        public event SocketAcceptedHandler SocketAccepted;
    }
}


Client(отвечает за приём данных, и контролем подключения)
Client.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.Net;
using System.Net.Sockets;
 
namespace lessonMultiServer
{
    class Client
    {
        public string     ID       { get; private set; } // поле ID соединения
        public IPEndPoint EndPoint { get; private set; } // конечная точка
 
        Socket sck;
        
        public Client(Socket accepted)
        {
            // создаём сокет для отдельного подкл
            sck = accepted;
 
            // Присваеваем индентификатор
            ID = Guid.NewGuid().ToString();
 
            // поле EndPoint = IP:Port подключенного клиента
            EndPoint = (IPEndPoint)sck.RemoteEndPoint;
 
            // Начинает выполнение асинхронного приема данных с подключенного объекта Socket
            sck.BeginReceive(new byte[] { 0 }, 0, 0, 0, callback, null);
        }
        void callback(IAsyncResult ar)
        {
            try
            {
                // Завершает отложенное асинхронное чтение
                sck.EndReceive(ar);
                
                byte[] buff = new byte[8192];
                int rec = sck.Receive(buff, buff.Length, 0);
 
                // rec < buf = увеличить rec
                if (rec < buff.Length) { Array.Resize<byte>(ref buff, rec); }
                // Если получаемые данные не пустые, заполняем буфер
                if (Received != null ) { Received(this, buff); }
                // Снова получаем данные
                sck.BeginReceive(new byte[] { 0 }, 0, 0, 0, callback, null);
 
 
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                Close();
 
                if (Disconnected != null) { Disconnected(this); }
            }
 
        }
 
        public void Close()
        {
            sck.Close();
            sck.Dispose();
        }
 
        public delegate void ClientReceivedHandler      (Client sender, byte[] data);
        public delegate void ClientDisconnectedHandler (Client sender);
 
        public event ClientReceivedHandler     Received;
        public event ClientDisconnectedHandler Disconnected;
    }
}


Ну и код с формы где всё используется, на форме имеется компонент ListView"Name=lstClient"
Form.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
using System.Net;
using System.Net.Sockets;
 
namespace lessonMultiServer
{
    public partial class Main : Form
    {
        Listener listener;
 
        public Main()
        {
            InitializeComponent();
            listener = new Listener(8);
 
            // вызываем метод из класса Listener
            listener.SocketAccepted += new Listener.SocketAcceptedHandler(listener_SocketAccepted);
 
            // При старте вкл прослушивание порта
            Load += new EventHandler(Main_Load);
        }
 
        // При старте вкл прослушивание порта
        void Main_Load(object sender, EventArgs e)
        {
            listener.Start();
        }
 
        void listener_SocketAccepted(System.Net.Sockets.Socket e)
        {
            //MessageBox.Show(e.RemoteEndPoint.ToString());
            Client client = new Client(e);
            
            //Вызываем методы из класса Client
            client.Received     += new Client.ClientReceivedHandler    (client_Received    );
            client.Disconnected += new Client.ClientDisconnectedHandler(client_Disconnected);
 
            // Представляет делегата, который может выполнить любой метод в управляемом коде, 
            // объявляемый с пустым списком параметров и не принимающий параметры.
            
            // много поточный процесс, чтоб не подвесать форму
            Invoke((MethodInvoker)delegate
            {
                // создаём список данных
                ListViewItem i = new ListViewItem();
                // название списка = IP:Port
                i.Text = client.EndPoint.ToString();
                //Вложеный список
                i.SubItems.Add(client.ID); // № соединения
                i.SubItems.Add("XX"); // последнее сообщение
                i.SubItems.Add("XX"); // Время последнего запроса
 
                i.Tag = client;
 
                lstClients.Items.Add(i);
            });
        }
 
        void client_Disconnected(Client sender)
        {
            Invoke((MethodInvoker)delegate 
            {
                    for (int i = 0; i < lstClients.Items.Count; i++)
                    {
                        // Tag - Получает или задает объект, 
                        // содержащий данные, сопоставленные данному элементу.
                        Client client = lstClients.Items[i].Tag as Client;
 
                        // пролетаем по всему списку
                        // если в спсиске попадается ID равный ID сокета вызваному метод
                        // то удаляем его из списка
                        if (client.ID == sender.ID)
                        {
                            lstClients.Items.RemoveAt(i);
                            break;
                        }
                    }
                
            });
            
        }
 
        void client_Received(Client sender, byte[] data)
        {
            Invoke((MethodInvoker)delegate 
            {
                    for (int i = 0; i < lstClients.Items.Count; i++)
                    {
                        Client client = lstClients.Items[i].Tag as Client;
 
                        // пролетаем по всему списку
                        // если в спсиске попадается ID равный ID сокета вызваному метод
                        // изменяем поля [2] - Последнее сообщение [3] - время
                        if (client.ID == sender.ID)
                        {
                            lstClients.Items[i].SubItems[2].Text = Encoding.Default.GetString(data);
                            lstClients.Items[i].SubItems[3].Text = DateTime.Now.ToString();
                            break;
                        }
                    }
                
            });
        }
    }
}


подскажите как и где описать событие чтоб можно было к примеру ответить на данные клиента "привет" данными от сервера "привет от сервера". Ато вроде как код по полочка разобрать разобрал, а такой момент очень важен для дальнейшего изучения!

Добавлено через 12 часов 22 минуты
Ладно в общем сам розрулил, к сожалению сделать делегативный метод в классе "Client" не получилось, поэтому я с него просто открыл доступ к сокету
C#
1
public Socket sck;
ну и уже стандартно передаю данные после принятия:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 void client_Received(Client sender, byte[] data)
        {
            Invoke((MethodInvoker)delegate 
            {
 
                    for (int i = 0; i < lstClients.Items.Count; i++)
                    {
                        Client client = lstClients.Items[i].Tag as Client;
                        
                        // пролетаем по всему списку
                        // если в спсиске попадается ID равный ID сокета вызваному метод
                        // изменяем поля [2] - Последнее сообщение [3] - время
                        if (client.ID == sender.ID)
                        {
                            lstClients.Items[i].SubItems[2].Text = Encoding.Default.GetString(data);
                            lstClients.Items[i].SubItems[3].Text = DateTime.Now.ToString();
 
                            if (Encoding.Default.GetString(data) == "Hello")
                            {
                                
                                byte[] data2 = Encoding.Default.GetBytes("Hi, from Server!");
 
                                client.sck.Send(BitConverter.GetBytes(data2.Length), 0, 4, 0);
                                client.sck.Send(data2);
                                
                            }
 
                            break;
                        }
                    }
      
            });
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.07.2012, 15:30
Ответы с готовыми решениями:

Как отправить данные с сервера в массив
Здравствуйте! Мне необходимо создать приложения клиент и сервер-это я сделал. Далее нужно запустить...

Проверка на стороне сервера, что клиент обработал отправленные данные
Есть клиент и есть сервер, общаются по именованому каналу (named pipe) Проблема: нужно сделать...

Клиент должен отправить файл на сервер. Сервер его обработать и отправить клиенту текст
Ребят подскажите как сделать: Клиент должен отправить файл на сервер. Сервер его обработать и...

Клиент-сервер. Клиент не принимает данные
Здравствуйте о светлейшие умы сего мира! Я работаю над одним проектом, а именно написание...

0
28.07.2012, 15:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.07.2012, 15:30
Помогаю со студенческими работами здесь

Клиент-сервер, отправить скриншот по запросу
Пытаюсь написать клиент-сервер программу, чтобы при клике клиент отправлял запрос серверу, сервер...

Отправить запрос с сервера клиенту
Здравствуйте. У меня возникла проблема. Нужно отправить запрос с сервера/сайта в программу и...

Как отправить byte[] с сервера клиенту через socket
Как отправить byte с сервера клиенту через socket? Я могу отправить с клиента на сервер вот так....

Клиент для UDP сервера!
Есть вот такой сервер: using System; using System.Collections.Generic; using System.Linq;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru