Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/34: Рейтинг темы: голосов - 34, средняя оценка - 5.00
68 / 68 / 42
Регистрация: 30.03.2015
Сообщений: 372
1

Работа с сокетами, основы клиент-серверного приложения

23.02.2016, 10:50. Показов 6761. Ответов 6
Метки нет (Все метки)

Нашел простой пример клиент-серверного приложения на C#:
Сервер:
Кликните здесь для просмотра всего текста
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
// SocketServer.cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
namespace SocketServer
{
    class Program
    {
        static void Main(string[] args)
        {
            // Устанавливаем для сокета локальную конечную точку
            IPHostEntry ipHost = Dns.GetHostEntry("localhost");
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);
 
            // Создаем сокет Tcp/Ip
            Socket sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
 
            // Назначаем сокет локальной конечной точке и слушаем входящие сокеты
            try
            {
                sListener.Bind(ipEndPoint);
                sListener.Listen(10);
 
                // Начинаем слушать соединения
                while (true)
                {
                    Console.WriteLine("Ожидаем соединение через порт {0}", ipEndPoint);
 
                    // Программа приостанавливается, ожидая входящее соединение
                    Socket handler = sListener.Accept();
                    string data = null;
 
                    // Мы дождались клиента, пытающегося с нами соединиться
                    
                    byte[] bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    
                    data += Encoding.UTF8.GetString(bytes, 0, bytesRec);
                    
                    // Показываем данные на консоли
                    Console.Write("Полученный текст: " + data + "\n\n");
                    
                    // Отправляем ответ клиенту\
                    string reply = "Спасибо за запрос в " + data.Length.ToString()
                            + " символов";
                    byte[] msg = Encoding.UTF8.GetBytes(reply);
                    handler.Send(msg);
 
                    if (data.IndexOf("<TheEnd>") > -1)
                    {
                        Console.WriteLine("Сервер завершил соединение с клиентом.");
                        break;
                    }
                    
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                Console.ReadLine();
            }
        }
    }
}

Клиент:
Кликните здесь для просмотра всего текста
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
// SocketClient.cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
namespace SocketClient
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                SendMessageFromSocket(11000);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                Console.ReadLine();
            }
        }
 
        static void SendMessageFromSocket(int port)
        {
            // Буфер для входящих данных
            byte[] bytes = new byte[1024];
 
            // Соединяемся с удаленным устройством
            
            // Устанавливаем удаленную точку для сокета
            IPHostEntry ipHost = Dns.GetHostEntry("localhost");
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, port);
            
            Socket sender = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            
            // Соединяем сокет с удаленной точкой
            sender.Connect(ipEndPoint);
 
            Console.Write("Введите сообщение: ");
            string message = Console.ReadLine();
 
            Console.WriteLine("Сокет соединяется с {0} ", sender.RemoteEndPoint.ToString());
            byte[] msg = Encoding.UTF8.GetBytes(message);
            
            // Отправляем данные через сокет
            int bytesSent = sender.Send(msg);
            
            // Получаем ответ от сервера
            int bytesRec = sender.Receive(bytes);
            
            Console.WriteLine("\nОтвет от сервера: {0}\n\n", Encoding.UTF8.GetString(bytes, 0, bytesRec));
 
            // Используем рекурсию для неоднократного вызова SendMessageFromSocket()
            if (message.IndexOf("<TheEnd>") == -1)
                SendMessageFromSocket(port);
            
            // Освобождаем сокет
            sender.Shutdown(SocketShutdown.Both);
            sender.Close();
        }
    }
}

Результат:
Кликните здесь для просмотра всего текста
Работа с сокетами, основы клиент-серверного приложения


Ссылка на источник: http://professorweb.ru/my/csha... l3/3_2.php

Локально все работает, теперь я хочу чтобы в роли сервера был мой настольный компьютер, а в роли клиента мой ноутбук, или любой другой компьютер подключенный к интернету.
Подскажите какие изменения необходимо внести в исходный код этих файлов, чтоб все заработало. На обоих системах стоит Visual Studio.
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.02.2016, 10:50
Ответы с готовыми решениями:

Неправильная работа клиент серверного приложения
Нашел в msdn исходники простых клиента и сервера, скомпилил в качестве консольных приложений - все...

Нестабильная работа клиент-серверного приложения
Например никнейм пользователя, может записаться в Memo а может и в ListBox1, или часы, могут...

Windows sockets приложения с сокетами, написание приложения сервер-клиент
Написать программу-сервер и программу - клиент. Клиент читает файл, пересылает его серверу. Сервер,...

Инсталлятор клиент-серверного приложения
Здравствуйте! Есть клиент-серверное приложение которое может работать с Firebird и SQLServer ...

6
68 / 68 / 42
Регистрация: 30.03.2015
Сообщений: 372
24.02.2016, 20:44  [ТС] 2
Попытался задать свой IP адрес:
C#
1
2
IPAddress ipAddr = IPAddress.Parse("212.42.120.70");
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);
Получил исключение:
Работа с сокетами, основы клиент-серверного приложения
0
Эксперт .NETАвтор FAQ
10299 / 5033 / 1821
Регистрация: 11.01.2015
Сообщений: 6,224
Записей в блоге: 34
24.02.2016, 21:05 3
Лучший ответ Сообщение было отмечено Constantius24 как решение

Решение

Constantius24,
1) В коде сервера создавайте IPEndPoint так:
C#
1
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 11000);
что означает, что сервер будет принимать соединения с любого IP.

2) В коде клиента переделайте метод SendMessageFromSocket так, что бы он принимал хост удаленного сервера:
Кликните здесь для просмотра всего текста
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
        static void SendMessageFromSocket(string host, int port)
        {
            // Буфер для входящих данных
            byte[] bytes = new byte[1024];
 
            // Соединяемся с удаленным устройством
            
            // Устанавливаем удаленную точку для сокета
            IPHostEntry ipHost = Dns.GetHostEntry(host);
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, port);
            
            Socket sender = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            
            // Соединяем сокет с удаленной точкой
            sender.Connect(ipEndPoint);
 
            Console.Write("Введите сообщение: ");
            string message = Console.ReadLine();
 
            Console.WriteLine("Сокет соединяется с {0} ", sender.RemoteEndPoint.ToString());
            byte[] msg = Encoding.UTF8.GetBytes(message);
            
            // Отправляем данные через сокет
            int bytesSent = sender.Send(msg);
            
            // Получаем ответ от сервера
            int bytesRec = sender.Receive(bytes);
            
            Console.WriteLine("\nОтвет от сервера: {0}\n\n", Encoding.UTF8.GetString(bytes, 0, bytesRec));
 
            // Используем рекурсию для неоднократного вызова SendMessageFromSocket()
            if (message.IndexOf("<TheEnd>") == -1)
                SendMessageFromSocket(host, port);
            
            // Освобождаем сокет
            sender.Shutdown(SocketShutdown.Both);
            sender.Close();
        }

3) При вызове метода SendMessageFromSocket вам нужно передавать в него IP адрес (или DNS имя) сервера. Если сервер находится в локальной сети, то это обычно адрес вида 192.168.0.***.
4) Если сервер находится в интернете, то вам нужно указать внешний IP адрес сервера. При этом сервер должен иметь статический IP. Если статического IP нет, нужно воспользоваться например DDNS.
5) Если сервер находится за роутером (в домашнем варианте, это обычно так и есть), то в роутере нужно прописать Port Forwarding для вашего порта, который будет указывать роутеру куда направлять входящие пакеты для данного порта.
2
68 / 68 / 42
Регистрация: 30.03.2015
Сообщений: 372
28.02.2016, 09:39  [ТС] 4
Storm23, изменил все как вы сказали. У меня динамический IP, посмотрел его на whoer.net, и вставил в качестве аргумента для метода SendMessageFromSocket. Словил исключение выхода за границы массива в этой строчке:
C#
1
IPAddress ipAddr = ipHost.AddressList[0];
0
Эксперт .NETАвтор FAQ
10299 / 5033 / 1821
Регистрация: 11.01.2015
Сообщений: 6,224
Записей в блоге: 34
28.02.2016, 10:54 5
Лучший ответ Сообщение было отмечено Constantius24 как решение

Решение

Цитата Сообщение от Constantius24 Посмотреть сообщение
исключение выхода за границы массива в этой строчке
Тогда замените строки
C#
1
2
3
            // Устанавливаем удаленную точку для сокета
            IPHostEntry ipHost = Dns.GetHostEntry(host);
            IPAddress ipAddr = ipHost.AddressList[0];
На

C#
1
2
3
4
            // Устанавливаем удаленную точку для сокета
            IPAddress ipAddr;
            if (!IPAddress.TryParse(host, out ipAddr))
                ipAddr = Dns.GetHostEntry(host).AddressList[0];
1
68 / 68 / 42
Регистрация: 30.03.2015
Сообщений: 372
28.02.2016, 11:09  [ТС] 6
Storm23, теперь такое исключение:
Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение
Да у меня стоит роутер, сейчас попробую его отключить и подключить напрямую кабель.

Добавлено через 6 минут
Отлично, есть результат!
Все заработало с моим DDNS, осталось теперь только роутер настроить.
---
Теперь по другому вопросу, если я хочу, чтобы клиентские приложения соединялись с моим компьютером, то как мне указать им IP который у меня постоянно меняется? Первая мысль которая мне пришла, это в приложении-сервер прописать обновление текстового файла в папке Dropbox в который прописывается текущий IP. Приложения-клиенты первым делом просматривают этот файл (у dropbox при обновлении файла, ссылка не меняется) и пытаются подключиться по указанному в нем IP.
0
25 / 28 / 19
Регистрация: 24.12.2014
Сообщений: 1,213
14.02.2017, 21:56 7
Цитата Сообщение от Constantius24 Посмотреть сообщение
еперь по другому вопросу, если я хочу, чтобы клиентские приложения соединялись с моим компьютером, то как мне указать им IP который у меня постоянно меняется? Первая мысль которая мне пришла, это в приложении-сервер прописать обновление текстового файла в папке Dropbox в который прописывается текущий IP. Приложения-клиенты первым делом просматривают этот файл (у dropbox при обновлении файла, ссылка не меняется) и пытаются подключиться по указанному в нем IP.
Тут уже лучше использовать сервер No-IP, так чтобы ip всегда был один и тот же для клиента.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.02.2017, 21:56

Создание клиент-серверного приложения
Здравствуйте! Вопрос наверное больше будет по теории. Если я его не в ту тему задал, то,...

Сборка клиент-серверного приложения
Доброго времени суток. Столкнулся с немного неадекватным требованием фирмы и прошу помочь с...

Создание клиент-серверного приложения
Доброго дня. Необходимо написать программу обращения матрицы, она должна быть клиент серверной, то...

Организация клиент-серверного приложения
Хочу создать некое К-С приложение, что-то типа системы оповещений. Но не знаю как осуществить...


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

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

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