клиент заканчивает соединение или сервер? - PullRequest
2 голосов
/ 01 апреля 2012

Я программирую приложение клиент-сервер. Мне интересно разорвать соединение, какая сторона должна решить разорвать его, клиент или сервер?

Тогда, если, например, клиент сделал это, должен ли сервер оставаться открытым или нет?

Предположим, у нас есть следующие коды для каждого клиента и сервера:

           socket = new Socket("127.0.0.1",3000);
........

            socket.close();

или

            serverSocket = new ServerSocket(3000);
            socket = serverSocket.accept();
......

            serverSocket.close();

EDIT: в соответствии с ответом Мэтта, я оставлю здесь свой код и посмотрим, почему мой код не работает:

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

Сервер

        private static PrintWriter toClient;
        private static BufferedReader fromClient;


  public static void run() throws IOException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException, SAXException, XPathExpressionException
        {


        System.out.println("Server is waiting for connections...");

        while(true)
        {
                 openStreams();
                  processClient();
                  closeStreams();
 }

    }

OpenStream:

  public static void openStreams() throws IOException, SAXNotRecognizedException, SAXNotSupportedException, ParserConfigurationException, SAXException, XPathExpressionException
            {
            serverSocket = new ServerSocket(3000);
            socket = serverSocket.accept();
                System.out.println("Connected");

             toClient = new PrintWriter(socket.getOutputStream(),true);

            fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));


            }

Closestearms:

   public static void closeStreams() throws IOException
            {
            fromClient.close();
            toClient.close();
            socket.close();
            serverSocket.close();
                System.out.println("Disconnected");
        }

ошибка, которую я получаю, если удаляю closestream();

at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
    at java.net.ServerSocket.bind(ServerSocket.java:319)
    at java.net.ServerSocket.<init>(ServerSocket.java:185)
    at java.net.ServerSocket.<init>(ServerSocket.java:97)

Ответы [ 3 ]

2 голосов
/ 01 апреля 2012

Зависит от логики вашего приложения.Оба действительны, и вы должны убедиться, что ваш код корректен в обоих случаях, так как, если соединение разорвано «невольно» (например, разрыв сети), оно будет отображаться с обеих сторон, как если бы другая сторона закрыла соединение.

Таким образом, ваш код должен корректно обрабатывать оба случая.

Ваш закрывающий код является подозрительным: вы закрываете сокет прослушивания, что необычно.Вы должны закрывать сокет прослушивания только тогда, когда вы не хотите больше входящих соединений (то есть обычно для сервера, когда вы выключаете сервер).
Только закройте сокет, который вы получили от accept, чтобы завершить это"разговор", и не открывайте сокет прослушивания сервера.(Исключением, которое вы получаете, может быть «Адрес уже используется» в этом случае. См. Как установить опцию повторного использования адреса для сокета дейтаграммы в коде Java? для примера того, как избежать этого конкретногопроблема.)

0 голосов
/ 01 апреля 2012

Сокет присутствует как в клиентской, так и в серверной программе.Закрытие любого сокета вызовет исключение на другой стороне.

0 голосов
/ 01 апреля 2012

Любой конец может закрыть соединение - ни один не "более правильный".

Однако важно устранить одно (кажущееся) недоразумение в вашем коде: закрытие ServerSocket не закрывает сокет, представляющий соединение между двумя конечными точками.

ServerSocket - это прослушивающий сокет на порту. Когда клиент устанавливает соединение с ServerSocket на этом порту, метод ServerSocket.accept () возвращает (нормальное) Socket. Связь между двумя вашими конечными точками использует входные и выходные потоки, связанные с этим (обычным) сокетом.

Закрытие ServerSocket просто прекращает прослушивание известного порта и не относится к установленным сокетам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...