Разумно ли использовать 3 порта для серверного приложения? - PullRequest
4 голосов
/ 21 марта 2012

У меня есть сервер-клиентское приложение [TCP-сокеты, .NET 4.0] ..
Приложение о:

делает команды, полученные от клиента получает файлы отправляет снимок экрана
приложение должно выполнять 3 задачи одновременно
После того, как я это сделал, и это сработало ... я понял, что приложения такого типа должны использовать один порт для всех задач .. как Radmin и netsupport .. и т.д.
но я использовал 3 порта .. один, чтобы продолжать получать команды в любое время, когда клиент отправляет. и один для получения файлов .. и один, если клиент попросил скриншот

так нормально ли использовать 3 порта для сетевого приложения? ..

Я пытался создать 3 сокета на стороне клиента для подключения к серверу на том же порту (например: 9090)
но когда я попытался отправить файл с клиента ... сервер получил байты в функции Job, которая должна принимать только команды ... так что похоже, что я не могу использовать один порт для этих задач
Можно ли использовать один порт для всех трех задач, чтобы они могли работать одновременно?

    private void ClientAccept()
    {
        while (true)
        {
            Socket client = server.Accept();
            Console.WriteLine(client.RemoteEndPoint + " has connected");
            NetworkStream stream = new NetworkStream(client);
            StreamReader reader = new StreamReader(stream);
            string line = reader.ReadLine();
            if (line == "1")           //it means its a command socket
            {
                thJob = new Thread(Job);
                thJob.Start(cmdClient);
            }
            else if(line=="2")        //its a data socket
            {
                FileTransfer ft = new FileTransfer(client);
            }
         }
      }

    private void Job(object o)
    {
        Socket s = (Socket)o;
        StreamReader sr = new StreamReader(new NetworkStream(s));
        string cmd = null;
        while ((cmd = sr.ReadLine()) != null)
        {
            //bla bla
        }
    }

Добавлен вопрос:
Допустим, сервер имеет один порт.
клиент подключается к серверу для команд .. давайте назовем его cmdClient с его портом 11589
, после чего для этого клиента запустился поток заданий, как при коде вверх. затем клиент соединяется с другим сокетом с сервером .. dataClient, чей порт 1800
, затем, когда я использую dataClient для отправки файла .. сервер получает байты в методе задания .. !! почему это счастливо?

Ответы [ 2 ]

2 голосов
/ 21 марта 2012

Да, разумно использовать несколько портов при передаче файлов.Это потребовало бы достаточно продвинутого протокола, чтобы использовать тот же порт и при этом сохранять ответ приложения (поскольку вы все еще должны иметь возможность отправлять команды во время передачи файлов).

Но я не рекомендую использовать три фиксированныхпорты.Используйте один порт для всех команд и произвольное количество портов для передачи файлов.

Передача файлов будет выглядеть следующим образом:

  1. (CmdPort) Клиент -> Сервер Эй, я хочу передать файл XXX с размером ГГГГ
  2. (CmdPort) Сервер -> Клиент Roger, подключиться к порту 8217 и передать файл
  3. (8217) Клиент -> Сервер Подключается, передает весь файл, отключается
  4. (8217) Сервер Проверяет, что переданный размер соответствует размеру, указанному в шаге # 1

Это позволяет передавать несколько файлов одновременно.Позвольте серверу создать новый сокет прослушивания, используя порт 0. Он говорит ОС выбрать свободный порт.Затем используйте Socket.LocalEndpoint, чтобы узнать порт перед отправкой его обратно на шаге 2.

Указанный подход также позволяет вам воспользоваться преимуществом Socket.SendFile, которое, вероятно, является наиболее эффективным и быстрым способом отправки файлов с использованием.NET.

(FTP использует тот же подход, что и bittorrent. Возможно, вы использовали файловый менеджер при загрузке файлов из Интернета. Они используют более экстремальный подход и разбивают загрузку файлов понесколько сокетов для обхода ограничения пропускной способности веб-сервера.)

обновление в ответ на комментарий:

мое приложение также отправляет папки, папкиможет иметь 2000 файлов, размер многих файлов может быть меньше килобайта, было бы огромной ошибкой подключаться к каждому файлу .. или, возможно, мне следует подключиться один раз для каждой задачи (папка / файл)

Вы не указали эту информацию в исходном вопросе, что заставило меня предположить, что вы передаете только один файл за раз.

Пакетная передача будет работатьТаким же образом, просто измените так, чтобы шаг # 1 отправлял список имени файла + размер, а затем отправлял все файлы один за другим на шаге № 3.

0 голосов
/ 21 марта 2012

Не рекомендуется использовать 3 порта, если каждая операция не является собственным приложением, т. Е. Файловым сервером, сервером изображений и т. Д. Вы должны создать одно приложение, прослушивающее 1 порт, а затем использовать Threading для принятия нескольких подключений к сервер (каждый со своим экземпляром StreamReader). Затем вы можете написать метод парсера для ввода данных пользователем. Например, если пользователь отправляет команду «ПОЛУЧИТЬ ФАЙЛ», сервер ожидает файл, если пользователь отправляет команду «ИЗОБРАЖЕНИЕ», сервер ожидает изображение.

Пример многопоточных серверов можно найти здесь:

http://csharp.net -informations.com / связь / CSharp-многопоточный-сервер-socket.htm

...