Почему метод accept объекта ServerSocket возвращает объект Socket с другим портом

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

JAVA Код:

package chat.server;

import java.io.*;
import java.net.*;

public class ServerApp {
    public String[] advices = {"Take smaller bites",
            "Go for the tight jeans. No they do NOT make you look fat.",
            "One word: inappropriate",
            "Just for today, be honest. Tell your boss what you *really* think",
            "You might want to rethink that haircut."};
    public ServerSocket serverSocket;

    public ServerApp()
    {
        try
        {
            serverSocket = new ServerSocket(4245);
            System.out.println("Server Started.");
        }catch (Exception exception)
        {
            exception.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ServerApp server = new ServerApp();
        while(true)
        {
                server.sendMessage();
        }

    }

    public void sendMessage()
    {
        String advice;
        try
        {
            Socket socket = serverSocket.accept();//here comes my question
            System.out.println(socket.getPort());
            PrintWriter printWriter = new PrintWriter(socket.getOutputStream());

            advice = getAdvice();
            printWriter.write(advice);

            printWriter.close();
            System.out.println(advice);
        }catch (Exception exception)
        {
            exception.printStackTrace();
        }
    }

    private String getAdvice() {
        int random = (int) (Math.random() * advices.length);
        return advices[random];
    }
}

Разве это не нормально, что сервер слушает и отвечает клиенту с одного и того же номера порта?


person Ramin    schedule 15.01.2014    source источник


Ответы (2)


Если вы хотите вернуть значение 4245 (порт, который прослушивает ваш серверный сокет) из подключенного сокета, вам нужен getLocalPort, а не getPort.

getPort:

Возвращает номер удаленного порта, к которому подключен этот сокет.

getLocalPort:

Возвращает локальный номер порта, к которому привязан этот сокет.

(выделено мной)

person T.J. Crowder    schedule 15.01.2014
comment
@Crowder, значит, вы имеете в виду порт клиентской машины, говоря об удаленном порту, к которому подключен этот сокет, верно? - person Ramin; 15.01.2014
comment
@1linecode: Верно. Сокет подключен к порту на обоих концах. (Вы, вероятно, знали это.) Порт клиентской машины является удаленным с точки зрения вашего сервера, поэтому локальным портом для вашего клиентского сокета будет порт на сервере, где прослушивался ваш серверный сокет. getPort дает вам удаленный порт на клиентской машине, который вряд ли будет одним и тем же (и будет варьироваться от соединения к соединению, даже с одной и той же машины). - person T.J. Crowder; 15.01.2014
comment
@Crowder, спасибо, сэр. - person Ramin; 15.01.2014

почему метод accept() объекта ServerSocket возвращает объект Socket, прослушивающий другой порт на серверной машине

Это не так. То, на что вы смотрите, это удаленный порт на стороне клиента. Локальный порт задается getLocalPort(), и совпадает с ServerSocket's.

NB Только ServerSocket "слушает". Принятый Socket подключен и готов к вводу-выводу.

person user207421    schedule 15.01.2014