Форум программистов, компьютерный форум, киберфорум
.NET
Войти
Регистрация
Восстановить пароль
 
quaziir
1
.NET 3.x

Сервер работает в локальной сети, но не функционирует, если использовать его в интернете

25.05.2010, 20:04. Показов 912. Ответов 0
Метки нет (Все метки)

Здравствуйте!

Я пишу сервер (под Windows, C#, Visual Studio 2008) для удаленного управления роботом (Robotino).
Столкнулся с вот какой трудностью.

Сервер написал с использованием асинхронных функций BeginAccept, BeginReceive и прочих.
Мой клиент отлично соединяется с сервером в локальной сети. Но по заданию, он должен работать через интернет.
Начал тестировать в инете. Использовал 2 способа:

1) приложение-сервер запускал на компьютере с выделенным IP;

2) используя Hamachi (позволяет создать локальную сеть поверх интернета), пытался соединиться клиентом через интернет с моим удаленным сервером Robotino. То есть как будто мы в одной сети. [этот способ походит, когда нет выделенного IP]

Пробовал разные порты - результат один и тот же:
ошибка "Запрос на отправку или получение данных (when sending on a datagram socket using a sendto call) no address was supplied".

Вот что странно - при соединении начальный коннект происходит - на сервер приходят имя пользователя и пароль. А дальше - дисконнект. У сервера вылетает: "Удаленный пользователь разорвал соединение".

Может что-то во времени ожидания? (пинг был 60 мс) Как я уже упоминал, в локальной все работает отлично.
Очень надеюсь на вашу помощь!

Фрагмент кода клиента

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
           try
            {
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
                IPAddress ipAddress = IPAddress.Parse(txtServerIP.Text);
 
                int tPort = Convert.ToInt32(txtServerPort.Text);
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, tPort);
 
                clientSocket.BeginConnect(ipEndPoint, new AsyncCallback(OnConnect), null);
 
                byteData = new byte[1024];
 
 
                clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
                                          new AsyncCallback(OnReceive), null);
            }
            catch (Exception ex) 
            {
                MessageBox.Show(ex.Message, "Сlient error", MessageBoxButtons.OK, MessageBoxIcon.Error);  // вот тут и имеем Exception
            }
Если пригодится - продолжение кода

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
private void OnReceive(IAsyncResult ar)
        {
            try
            {
                clientSocket.EndReceive(ar);
                Data msgReceived = new Data(byteData);
                switch (msgReceived.cmdCommand)
                {
                    case Command.Login:    //проверка: принял ли сервер данные пользователя
                        if (!(msgReceived.strMessage == "Error Username or Password"))
                        {
                            strName = txtName.Text;
                            DialogResult = DialogResult.OK;
                            Close();
                        }
                        else
                        {
                            strName = txtName.Text;
                            MessageBox.Show( "Error Username or Password. Please, input incorrect data!","SGSClientTCP: "+strName,MessageBoxButtons.OK,MessageBoxIcon.Error);
                        }
                        break;
                }
            }
            catch (ObjectDisposedException)
            { }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "СlientTCP: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
 
        private void OnSend(IAsyncResult ar)
        {
            try
            {
                clientSocket.EndSend(ar);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "44SGSclient", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
 
        private void OnConnect(IAsyncResult ar)
        {
            try
            {
                clientSocket.EndConnect(ar);
                //Установлено соединение, произведем вход на сервер
                Data msgToSend = new Data ();
                msgToSend.cmdCommand = Command.Login;
                msgToSend.strName = txtName.Text;
                msgToSend.strMessage = txtPass.Text;
 
                byte[] b = msgToSend.ToByte ();
                //Отослать сообщения на сервер
                clientSocket.BeginSend(b, 0, b.Length, SocketFlags.None, new AsyncCallback(OnSend), null);
            }
            catch (Exception ex)
            { 
                MessageBox.Show(ex.Message, "55SGSclient", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
А это - фрагмент кода сервера:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
try
            {
                //Используем TCP-сокеты
                serverSocket = new Socket(AddressFamily.InterNetwork,
                                          SocketType.Stream,
                                          ProtocolType.Tcp);
                //Назначаем любой IP машины и слушаем порт 1200
                int tPort = Convert.ToInt32(toolStripTextBoxPort.Text);
                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, tPort);
 
                //Связываем(Bind) и слушаем сеть
                serverSocket.Bind(ipEndPoint);
                serverSocket.Listen(1000);
 
                //Прием входящего соединения
                serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
                statusLabel.Text = "Статус: сервер включен.";
            }
            catch (Exception ex)  // Обработка исключения
            {
                MessageBox.Show(ex.Message, "SGSserverTCP [1]",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        private void OnAccept(IAsyncResult ar)
        {
            try
            {
                Socket clientSocket = serverSocket.EndAccept(ar);
 
                //Начинаем прослушивание, ожидая других клиентов
                serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
 
                //После подключения клиент, начаем получать команды от него
                clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, 
                    new AsyncCallback(OnReceive), clientSocket);                
            }
            catch (Exception ex) //Обработка исключений
            { 
                MessageBox.Show(ex.Message, "SGSserverTCP [2]", 
                                MessageBoxButtons.OK, MessageBoxIcon.Error); 
            }
        }
При попытке соединения сервер выдает: MessageBox.Show(ex.Message, "SGSserverTCP [3]", MessageBoxButtons.OK, MessageBoxIcon.Error); Пользователь разорвал соединение

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
private void OnReceive(IAsyncResult ar)
        {
            try
            {
                Socket clientSocket = (Socket)ar.AsyncState;
                clientSocket.EndReceive(ar);
 
                // Преобразование массива байт, полученных от пользователя,
                // в форму объекта Data
                Data msgReceived = new Data(byteData);
 
                //Этот объект мы будем отсылать на запросы пользователей
                Data msgToSend = new Data();
 
                byte[] message;
                bool loggedOn = false;
 
                // Если сообщение является Войти, выход, или простое текстовое сообщение,
                // то при отправке другим пользователям, тип сообщения остается неизменным
                msgToSend.cmdCommand = msgReceived.cmdCommand;
                msgToSend.strName = msgReceived.strName;
 
                if (msgReceived.cmdCommand == Command.Login)
                {
                    foreach (AccountsData Account in DataBase)
                    {
                        if (Account.userName == msgReceived.strName && Account.userPass == msgReceived.strMessage)
                        {
                            loggedOn = true;
                            break;
                        }
                    }
 
                    if (loggedOn)
                    {
                        // Когда пользователь входит на сервер, мы добавляем его
                        // в список клиентов
                        ClientInfo clientInfo = new ClientInfo();
                        clientInfo.socket = clientSocket;
                        clientInfo.strName = msgReceived.strName;
                        clientInfo.activ = true;
                        clientList.Add(clientInfo);
                        // Готовим текст сообщения для массовой рассылки
                        msgToSend.strMessage = "*** " + msgReceived.strName + " has joined server";
                        //!!! тут добавить изменение флага в массиве авторизации
                        message = msgToSend.ToByte();
                        clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None,
                               new AsyncCallback(OnSend), clientSocket);
                    }
                    else
                    {
                        msgToSend.cmdCommand = Command.Login;
                        msgToSend.strMessage = "Error Username or Password";
                        message = msgToSend.ToByte();
                        clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                new AsyncCallback(OnSend), clientSocket);
                        //clientSocket.Close();
                    }
 
                }
 
                bool AcceptClient = false;
                foreach (ClientInfo client in clientList)
                {
                    if (client.socket == clientSocket && client.activ == true)
                    {
                        AcceptClient = true;
                        break;
                    }
                }
                
 
                if (AcceptClient)
                {
                    switch (msgReceived.cmdCommand) // Обработка полученной команды
                    {
                        case Command.Logout:
                            // Если пользователь хочет выйти из сервера, мы ищем его
                            // в списке клиентов и закрываем соответствующие связи
                            int nIndex = 0;
                            foreach (ClientInfo client in clientList)
                            {
                                if (client.socket == clientSocket)
                                {
                                    clientList.RemoveAt(nIndex);
                                    break;
                                }
                                ++nIndex;  // Отсчитываем индекс в цикле foreach
                            }
                            clientSocket.Close();
                            //Массовая рассылка - клиент вышел
                            msgToSend.strMessage = "*** " + msgReceived.strName + " has left server";
                            break;
 
                        case Command.Message:
                            // Готовим текст сообщения, который мы будет транслировать для всех пользователей
                            msgToSend.strMessage = msgReceived.strName + ": " + msgReceived.strMessage;
                            MF.textBox1.Text = msgReceived.strMessage;
                            /*
                            if (msgReceived.strMessage == "GO!")
                            {
                                MF.textBox1.Text = "GO!";
                                //MF.Visible = true;
                                msgReceived.strMessage = "OK!";
                            }
                            if (msgReceived.strMessage == "FWD")
                            {
                                MF.textBox1.Text = "FWD";
                                MF.Visible = true;
                                msgReceived.strMessage = "OK! FWD";
                            }   */
                            break;
 
                        case Command.List:
                            // Отсылаем имена всех присутствующих пользователей новому пользователю
                            msgToSend.cmdCommand = Command.List;
                            msgToSend.strName = null;
                            msgToSend.strMessage = null;
 
                            // Собираем имена всех пользователей
                            foreach (ClientInfo client in clientList)
                            {
                                //Для упрощения, используем маркер разделения имен пользователей
                                msgToSend.strMessage += client.strName + "*";
                            }
                            message = msgToSend.ToByte();
 
                            //Отсылаем имена всех пользователей
                            clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                    new AsyncCallback(OnSend), clientSocket);
                            break;
                    }
 
                    if (msgToSend.cmdCommand != Command.List)   //Не List, так как List уже отослан
                    {
                        message = msgToSend.ToByte();
 
                        foreach (ClientInfo clientInfo in clientList)
                        {
                            if (clientInfo.socket != clientSocket || msgToSend.cmdCommand != Command.Login)
                            {
                                // Если не команда Login, то отсылаем всем,
                                // кроме приславшего (clientSocket)
                                clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                    new AsyncCallback(OnSend), clientInfo.socket);
                            }
                        }
 
                        txtLog.Text += DateTime.Now.ToString() + "> " + msgToSend.strMessage + "\r\n";   
                    }
 
                    //Если пользователь не выходит, значит мы его слушаем
                    if (msgReceived.cmdCommand != Command.Logout)
                    {
                        //Начинаем слушать пользователя
                        clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
                    }
 
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "SGSserverTCP [3]", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.05.2010, 20:04
Ответы с готовыми решениями:

Сервер Counter-Strike 1.6 виден в локальной сети, но не виден в интернете
Подскажите пожалуйста.Скачал сервер CS 1.6, запустил его как надо, открыл порты в брандмауэр...

Организация чата в Интернете. Как модифицировать код для локальной сети
Здравствуйте коллеги! Есть программка, брандмауэром разрешена... Чат по локальной сети работает...

Подскажите бесплатное ПО для создания виртуальной локальной сети в интернете работающее как Windows так и в Linux
Всех приветствую! Необходимо обьединить через интернет несколько компов как на Windows так и на...

Смена настройки параметра сети (использовать или не использовать прокси-сервер для локальных подключений)
Всем доброго дня! Опишу сложившуюся ситуацию: На работу постоянно хожу с домашним ноутом. У нас в...

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.05.2010, 20:04

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Не виден сервер в локальной сети
Приветствую всех. Подскажите, в какую сторону копать... Ситуация такая: 1 комп (ubuntu server) +...

Как скачать на сервер файл по его адресу в интернете
Есть в форме поле для выбора файла: <input type="file">. А как сделать, чтобы выбирался файл не со...

С Android-устройства на сервер в локальной сети
Задача: Андроид приложение с несколькими полями для ввода и кнопкой "отправить". После заполнения...

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

FTP сервер вне локальной сети
Привет! Помогите разобраться в вопросе. Есть FTP сервер в FileZilla по 192.168.0.104 -...

DNS сервер в небольшой локальной сети
Есль ли смысл оборудовать небольшую локальную сеть из 15 машин (сеть подключена к Internet) DNS...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.