Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сервер работает в локальной сети,но не в интернете, Ошибка при работе в интернете 
:(
    Опции темы
quaziir
Дата 25.5.2010, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 25.5.2010

Репутация: нет
Всего: нет



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

Я пишу сервер (под 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 мс) Как я уже упоминал, в локальной все работает отлично.
Очень надеюсь на вашу помощь!

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

Код

            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
            }


Если пригодится - продолжение кода

Код

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);
            }
        }


А это - фрагмент кода сервера:

Код
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);
            }



Код
        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); Пользователь разорвал соединение 

Код
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);
            }
        }

PM MAIL   Вверх
Pit_Bul
Дата 26.5.2010, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 2.10.2006

Репутация: нет
Всего: 1



варианта 2:

1. Как мне кажется самый правильный, не париться с Socket а использовать WCF либо WEB сервисы
2. Вместо пресловутого Hamachi создавать нормальное VPN соединение между клиентом и сервером
PM MAIL WWW   Вверх
Выхухоль
Дата 27.5.2010, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 85
Регистрация: 9.10.2008
Где: Ташкент

Репутация: нет
Всего: 2



попробуй в сервере
Код

IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, tPort);

IPAddress.Any поменать на внешний интернет адресс машины

если не проканает, напиши полный текст ошибки and Stack Trace and other info.

Это сообщение отредактировал(а) Выхухоль - 27.5.2010, 14:35
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0833 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.