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

TCP/IP клиент-сервер

16.11.2009, 03:04. Показов 21375. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите пожалуйста, как реализовать взаимодействие клиентского и серверного приложения по протоколу TCP/IP, если работают они в разных локальных сетях, а сервер находится на компе со статичным IP. (Локальные сети имеют доступ в интернет)
Пробовал юзать "Сетевое программирование для профессионалов" Кровчука, но не смог разобраться...
Аналогичная задача для приложений одной локалки была решена по примеру из этой книги.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.11.2009, 03:04
Ответы с готовыми решениями:

TCP клиент-сервер
Есть у кого нибудь простой работающий пример TCP соединения клиент-сервер допустим для отправки...

Клиент-сервер TCP через маршрутизатор
Пишу программу для сетевого взаимодействия клиент-сервер. Назначение - возможно чат. Писал на...

TCP клиент-сервер через интернет
Ситуация такая: Есть два компа. На одном сервер на другом клиент. Все реализована на...

TCP (Клиент-сервер) - потеря данных
Добрый день, меня интересует такой вопрос, я имею два приложения клиент-сервер написанные на TCP с...

16
463 / 340 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
16.11.2009, 04:37 2
Компьютер-сервер должен иметь не только статический IP внутри своей сети, но и в интернете (выделенный IP). Чтоб клиенты из другой сети могли обращаться к нему напрямую.
Иначе технология NAT будет ''убивать'' все пакеты идущие извне, которым несопоставлены исходящие пакеты.

Добавлено через 4 минуты
Поищите в этой ветви форума. Я ранее создавал похожую тему и был найден вполне подходящий выход.

Добавлено через 17 минут
Вот ссылка на тему:
https://www.cyberforum.ru/dotn... page2.html
1
0 / 0 / 0
Регистрация: 16.11.2009
Сообщений: 6
16.11.2009, 15:09  [ТС] 3
С выделенной линией тоже не получается... Обращаюсь на прямую...
Сервер писал вот так (пример из книги):

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
using Microsoft.WindowsMobile;
using Microsoft.WindowsMobile.PocketOutlook;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string HostName = Dns.GetHostName();
            IPHostEntry ipHost = Dns.Resolve(HostName);
            IPAddress ipAddr = ipHost.AddressList[1];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);
 
            Socket sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
            try
            {
                sListener.Bind(ipEndPoint);
                sListener.Listen(10);
 
                while (true)
                {
                    Console.WriteLine("Waiting for a conection on port "+ipEndPoint);
 
                    Socket handler = sListener.Accept();
 
                    string Data = null;
 
                    while (true)
                    {
                        byte[] bytes = new byte[1024];
                        int bytesRec = handler.Receive(bytes);
 
                        Data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
 
                        if (Data.IndexOf("<TheEnd>") > -1)
                        {
                            break;
                        }
                    }
                    Console.WriteLine("Text received: " + Data);
 
                    string theReply = "Thank you for those  " + Data.Length.ToString() + "  characties .  .  .";
                    byte[] msg = Encoding.ASCII.GetBytes(theReply);
                    handler.Send(msg);
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Console.Read();
 
            }
        }
    }
}
Клиент:
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
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Test
{
    class TcpClient
    {
        public static void Main()
        {
            byte[] bytes = new byte[1024];
            try
            {
 
                IPHostEntry ipHost = Dns.Resolve("***.***.***.***"); //тут пишу статичный IP
                IPAddress ipAddr = ipHost.AddressList[0];
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);
 
                Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sender.Connect(ipEndPoint);
 
                Console.WriteLine("Socket connected {0}",
                                   sender.RemoteEndPoint.ToString());
                string theMessage = "Proverka svyazi!";
 
                byte[] msg = Encoding.ASCII.GetBytes(theMessage + "  <TheEnd>");
                int bytesSent = sender.Send(msg);
                int bytesRec = sender.Receive(bytes);
 
                Console.WriteLine("The server says : {0}", Encoding.ASCII.GetString(bytes, 0, bytesRec));
 
                sender.Shutdown(SocketShutdown.Both);
                sender.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception {0}",e.ToString());
                Console.Read();
            }
            
        }
    }
}
Запускал серверное, но клиент не подключался, в окне консоли пишет, что недождался ответа...
0
463 / 340 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
16.11.2009, 15:55 4
Я же объяснил, что клиент не найдет сервера и не получит от него ответа. Даже если посылать пакеты на шлюз сети сервера, он не будет знать кому их посылать дальше... Перейдите по данной мною ссылке. Там в последних сообщениях был найден выход.
0
0 / 0 / 0
Регистрация: 16.11.2009
Сообщений: 6
17.11.2009, 00:22  [ТС] 5
Я смотрел, но не очень понял как это работает(((
Подскажите пожалуйста, где можно поподробнее почитать про этот механизм?
0
463 / 340 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
17.11.2009, 01:31 6
О технологии NAT:
http://ru.wikipedia.org/wiki/NAT

Сайт, который может помочь:
http://www.no-ip.com/

В чем, собственн, задум: Вы регистрируетесь, скачиваете маленькое приложение, устанавливаете на компьютере-сервере, в приложении жмете на кнопку для регистрации адреса.
Когда зарегистрируете адрес, в приложениях-клиентах будете посылать пакеты на этот адрес, а они будут перенаправлены на компьютер-сервер через установленное приложение.
Я тоже сталкивался с такой проблемой и нашел только два выхода: выделенный IP или передача через это приложение. Первый вариант меня никак не устраивал.

Добавлено через 2 минуты
Только в клиентах придется использовать не IP, а адрес, который вы зарегистрировали
0
0 / 0 / 0
Регистрация: 16.11.2009
Сообщений: 6
18.11.2009, 02:06  [ТС] 7
body90,
Спасибо, с приложением вроде разобрался, но пока не тестил... завтра попробую...
Но всё же с выделенным IP у меня тоже не получилось, не знаете в чём может быть причина?
0
463 / 340 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
18.11.2009, 02:26 8
Если у компьютера-сервера выделенный IP и в клиентах, имеющих доступ к интернету, вы посылали пакеты на него, то всё должно работать. А какую теперь Вы получаете ошибку?
1
0 / 0 / 0
Регистрация: 16.11.2009
Сообщений: 6
18.11.2009, 02:30  [ТС] 9
))))
Всё ту же...Говорит не дождался ответа... (на клиенте)
0
463 / 340 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
18.11.2009, 02:45 10
А на компьютере-клиенте точно только одно сетевое подключение?
Может стоит поэкспериментировать с кодексом в строке
... = ipHost.AddressList[0];
?
0
0 / 0 / 0
Регистрация: 16.11.2009
Сообщений: 6
18.11.2009, 16:35  [ТС] 11
body90,
спасибо большое, я разобрался, теперь всё работает)
Всё дело было в том, что сервер слушал только себя, ну типо только свой же IP...
глупость написал

C#
1
2
3
4
5
6
...
string HostName = Dns.GetHostName();
IPHostEntry ipHost = Dns.Resolve(HostName);
IPAddress ipAddr = ipHost.AddressList[1];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);
...
вместо этого например можно так (слушает всех на порту 11000):

C#
1
2
3
4
5
6
7
...
int PORT = 11000;
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, PORT); 
Socket sListener = new Socket(AddressFamily.InterNetwork,
                                           SocketType.Stream, 
                                           ProtocolType.Tcp);
...
Это всё из-за отсутствия опыта в подобных вещах...
Думаю, что тема закрыта, ещё раз спасибо)
0
463 / 340 / 19
Регистрация: 26.05.2009
Сообщений: 2,696
19.11.2009, 02:50 12
У меня не было возможности проверить Ваш код на компьютере, а просматривая его, не обратил внимания на эту деталь. Рад, что у Вас получилось. Честно говоря, в первый раз у меня была та же самая ошибка.
0
9 / 11 / 3
Регистрация: 21.11.2009
Сообщений: 56
21.11.2009, 21:23 13
там немного другой код
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
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
 
namespace CoD_Client
{
    class Program
    {
        //Назначаем порт для серверa , как целое 32х битное число (int)
        private const int EhcoPort = 3333;
 
        static void Main(string[] arg)
        {
            //пишем строчку в консоль
            Console.Write("Логин: ");
            // Назначим переменную username как текст юникод - ввод строчки с консоли и нажатие ентера
            string username = Console.ReadLine();
            //выведем сообщение в консоль
            Console.WriteLine("<-----Loged in----->");
            //попытка
            try
            {
                //Создаем соединение с сервером
                TcpClient eClient = new TcpClient("127.0.0.1", EhcoPort);
 
               
                //создаем классы потоков
                StreamReader readerStream = new StreamReader(eClient.GetStream());
                NetworkStream writerStreem = eClient.GetStream();
                string datatoSend;
                datatoSend = username;
                datatoSend += "\r\n";
                //отправляенм имя пользователя на сервер
                byte[] data = Encoding.ASCII.GetBytes(datatoSend);
 
             
                writerStreem.Write(data, 0, data.Length);
 
                //пока истина
                while (true)
                {
                    Console.Write(username + " : ");
                    //считываем строку с сервера
                    datatoSend = Console.ReadLine();
                    datatoSend += "\r\n";
                    data = Encoding.ASCII.GetBytes(datatoSend);
                    writerStreem.Write(data, 0, data.Length);
                    //если отправлена команда quit
                    if (datatoSend.IndexOf("Quit") > -1)
                        break;
                    string returndata;
                    //получить ответ от сервера
                    returndata = readerStream.ReadLine();
                    Console.WriteLine("Server" + returndata);
                }
                eClient.Close();
                
            }
            catch (Exception exc)
            {
                Console.WriteLine("server: " + exc);
                Console.ReadLine();
               
                
            }
 
        }
    }
}

уменя вопрос следующий:
как хациклить это чудо ?
после получения ошибки что бы начинал соеденяться заново (после Console.ReadLine()

return не пашит.
0
73 / 73 / 10
Регистрация: 04.12.2008
Сообщений: 458
22.11.2009, 16:45 14
циклом while там где тебе нужно (после Console.ReadLine()
0
9 / 11 / 3
Регистрация: 21.11.2009
Сообщений: 56
23.11.2009, 20:35 15
Цитата Сообщение от patriot2008 Посмотреть сообщение
циклом while там где тебе нужно (после Console.ReadLine()
неа, никуда не ретурнит, закрывается программка и все ((
0
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
24.11.2009, 18:52 16
не совсем понятно, что именно зациклить. От чего, до чего?
0
9 / 11 / 3
Регистрация: 21.11.2009
Сообщений: 56
27.11.2009, 21:48 17
Цитата Сообщение от Green Посмотреть сообщение
не совсем понятно, что именно зациклить. От чего, до чего?
я ж написал в какое место надо ретурн вставить.

там же происходит вылов глюков типа "сервер отверг соединение" или "нету связи с сервером"

в идеале нужно подождать 10 секунд и повторить попытку конекта к серверу.
0
27.11.2009, 21:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.11.2009, 21:48
Помогаю со студенческими работами здесь

Клиент-сервер: Как определить, что клиент отключился?
Привет. Есть клиент и сервер, при подключении клиента, на сервере создается класс, который содержит...

Клиент-серверное приложение: как определить, что сервер/клиент не отвечает в течении определенного времени
Пишу клиент-серверное приложение. Использую TCPListener и TCPClient. Вопрос: как определить что...

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

TCP: организация клиент-серверного приложения
Подскажите, пожалуйста, как реализовать клиент-серверное приложение, которое: Клиент: 1 кнопка,...


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

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

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