Простая программа сервера / клиента получает ошибку: java.net.ConnectException: соединение отказано

Я пытаюсь написать простой мессенджер, похожий на его пример в книге (Java How To Program 9th Edition, Пол Дейтель, Харви Дейтель, часть 27.6). после того, как я закончил, я пытаюсь проверить это. он работает на локальном хосте (127.0.0.1), также работает на компьютере, который подключает тот же модем (я имею в виду ips, такой как 192.168.0.1 и т. д.), но когда я хочу протестировать его на каком-либо компьютере через Интернет, клиентский код получил ошибку соединения, отказанную в соединении, Я думаю, когда мой клиент (который является моим другом где-то в моем городе) пытается подключиться к серверу (который является мной, опять же где-то в городе), когда он вводит мой ip, чтобы соединить меня, он подключается к моему модему и моему модему Не посылайте мне эту информацию (трудно объяснить что-то, что вы не можете глубоко понять на любом родном языке, поэтому мне очень жаль), любая помощь важна для меня.

вот код сервера

//:D
//hello every Body:! this is my first program which use some networks !!! :-khatkeif
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.EOFException;
public class Server extends JFrame
{
    JTextField enteredText;//input message from user
    JTextArea displayArea;//display information to user
    ObjectInputStream input;//input object from cilent
    ObjectOutputStream output;//output Object to client
    ServerSocket server;//server Socket
    Socket connection;//connecton to cilent
    public Server()//constructor
    {
        super("Server");
        setLayout(new BorderLayout(5,5));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(new JLabel("Server Messenger"),BorderLayout.NORTH);
        enteredText= new JTextField("entered message here");
        enteredText.setEditable(false);
        enteredText.addActionListener(new TextHandler());
        add(enteredText,BorderLayout.SOUTH);
        displayArea= new JTextArea();
        displayArea.setEditable(false);
        add(new JScrollPane(displayArea),BorderLayout.CENTER);
        setSize(500,500);
        setVisible(true);
    }
    public void runServer()
    {
        try
        {
            server = new ServerSocket(12345,10);//create server Socket
            while(true)
            {
                waitForConnection();//wait util a client want to connect
                openStreams();//open streams for send/get data
                processConnection();//recive message from client
            }
        }
        catch(IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
    public void waitForConnection() throws IOException
    {
        displayMessage("waiting for client");
        connection=server.accept();//alow server for connection
        displayMessage("connect to "+connection.getInetAddress().getHostName());        
    }
    public void openStreams() throws IOException//open stream that help me to send and recive message
    {
        displayMessage("setting I/O");
        output= new ObjectOutputStream(connection.getOutputStream());//create output to send message
        output.flush();//send headers to client
        input = new ObjectInputStream(connection.getInputStream());//create input from client message
        displayMessage("Got I/O");
    }
    public void processConnection() throws IOException//recive message from client & alow server to send message to client
    {
        try
        {
            displayMessage("connected successfully");
            setTextEditable(true);//alow server to send message to client
            String reciveMessage = (String)input.readObject();//recive message form client
            while(!reciveMessage.equals("TERMINATE"))//if client send this string,make process connection finish
            {
                displayMessage(connection.getInetAddress().getHostName()+">>> "+reciveMessage);//display clinet message in display erea
                reciveMessage=(String)input.readObject();//read next message
            }
        }
        catch(ClassNotFoundException cnfe)
        {
            cnfe.printStackTrace();
        }
        displayMessage(connection.getInetAddress().getHostName()+" disconnect`");
        close();
    }
    public void close() throws IOException//close every thing
    {
        sendMessage("TERMINATE");
        input.close();
        output.close();
        connection.close();
        setTextEditable(false);
        displayMessage("connection terminated");
    }
    public void setTextEditable(final boolean val)//set text field editable
    {
        SwingUtilities.invokeLater
        (
            new Runnable()
            {
                public void run()
                {
                    enteredText.setEditable(val);
                }
            }
        );

    }
    public void displayMessage(final String message)//display message in displayArea
    {
        SwingUtilities.invokeLater(
            new Runnable()
            {
                public void run()
                {
                    displayArea.append(message+"\n");
                }
            }
        );
    }
    public void sendMessage(String message) throws IOException//send message to client
    {
        output.writeObject(message);
        output.flush();
        displayMessage("Me>>> "+message);
        enteredText.setText("");
    }
    private class TextHandler implements ActionListener//when user press enter a text in enteredText send to client
    {
        public void actionPerformed(ActionEvent ev) 
        {
            try
            {
                sendMessage(ev.getActionCommand()); 
            }
            catch(IOException ioe)
            {
                ioe.printStackTrace();
            }
        }
    }
}

и это главное

//:D
public class ServerRun
{
    public static void main(String[] args)
    {
        Server server = new Server();
        server.runServer();
    }
}

давайте для кода клиента:D

//:D
//this is client side
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.InetAddress;
public class Client extends JFrame
{
    JTextField enteredText;//user input message
    JTextArea displayArea;//display information
    ObjectOutputStream output;//send message to server
    ObjectInputStream input;//recive message from server;
    Socket connection;//connection to server
    String serverInfo;//server name
    JButton closeB;
    JPanel downPanel;
    public Client ()
    {
        super("Client");
        setLayout(new BorderLayout(5,5));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(new JLabel("Client Messenger"),BorderLayout.NORTH);
        enteredText= new JTextField("Enter message Here");
        setTextEditable(false);
        enteredText.addActionListener(
            new ActionListener()
            {               
                public void actionPerformed(ActionEvent ev) 
                {
                    try
                    {
                        sendMessage(ev.getActionCommand());
                    }               
                    catch(IOException ioe)
                    {
                        ioe.printStackTrace();
                    }
                }
            }
        );
        closeB= new JButton("close");
        closeB.addActionListener(
            new ActionListener()
            {
                public void actionPerformed(ActionEvent ev)
                {
                    try
                    {
                        close();
                    }
                    catch(IOException ioe)
                    {
                        ioe.printStackTrace();
                    }
                }
            }
        );
        downPanel= new JPanel(new BorderLayout(5,5));
        downPanel.add(enteredText,BorderLayout.CENTER);
        downPanel.add(closeB,BorderLayout.EAST);
        add(downPanel,BorderLayout.SOUTH);
        displayArea= new JTextArea();
        displayArea.setEditable(false);
        add(new JScrollPane(displayArea),BorderLayout.CENTER);
        setSize(500,500);
        setVisible(true);
    }
    public void runClient(String host)//run client program
    {
        try
        {
            connectToServer(host);
            openStreams();
            processConnection();
        }
        catch(IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
    public void connectToServer(String host) throws IOException//connect to server
    {
        displayMessage("connceting to " + host);
        connection = new Socket(InetAddress.getByName(host),12345);//create connection to server 
    }
    public void openStreams() throws IOException // open streams for recive/send messages
    {
        output= new ObjectOutputStream( connection.getOutputStream());//create output for send messages
        output.flush();//send headers
        input = new ObjectInputStream(connection.getInputStream());//create input for recive messages
        displayMessage("connected to "+connection.getInetAddress().getHostName());
    }
    public void processConnection()throws IOException //recive message util server trminate
    {
        try
        {
            setTextEditable(true);//alow user to send message
            String reciveMessage=(String) input.readObject();
            while(!reciveMessage.equals("TERMINATE"))
            {
                displayMessage(connection.getInetAddress().getHostName()+">>> "+reciveMessage);
                reciveMessage=(String)input.readObject();
            }
            displayMessage("connection lost");
        }
        catch(ClassNotFoundException cnfe)
        {
            displayMessage("server message is not clear");
        }
    }
    public void close() throws IOException//close every thing
    {
        sendMessage("TERMINATE");
        input.close();
        output.close();
        connection.close();
        System.exit(0);
    }
    public void sendMessage(String message) throws IOException//send message to server
    {
        output.writeObject(message);//send message to server
        output.flush();//send headers
        displayMessage("Me>>> "+message);//displate sent message to user
        enteredText.setText("");
    }
    public void displayMessage(final String message)
    {
        SwingUtilities.invokeLater(
            new Runnable()
            {
                public void run()
                {
                    displayArea.append(message+"\n");
                }
            }
        );
    }
    public void setTextEditable(final boolean val)
    {
        SwingUtilities.invokeLater(
            new Runnable()
            {
                public void run()
                {
                    enteredText.setEditable(val);
                }
            }
        );
    }
}

и это главное:

//:D
import javax.swing.JOptionPane;
public class ClientRun
{
    public static void main(String args[])
    {
        Client client = new Client();
        client.runClient(JOptionPane.showInputDialog(null,"please enter host IP:"));
    }
}

еще раз спасибо

2 ответа

Решение

Предисловие: Это, скорее всего, не проблема с вашим кодом, а скорее проблема с настройкой вашей сети. (Похоже, @dimoniy избил меня до ответа, надеюсь, это пошлет ту же идею, что и его).

Наиболее вероятная причина, по которой ваш друг не может подключиться к вашему серверу, заключается в том, что он не может пройти через ваш модем. Для того, чтобы кто-то подключился к вашему серверу (из кода порт выглядит следующим образом: 12345) вам нужно изменить некоторые настройки в маршрутизаторе / модеме (к которым вы обычно можете подключиться, перейдя в 192.168.1.1 или 192.168.0.1) и добавив "правило переадресации портов". Это позволит подключаться "за пределами" вашей сети (так называемый остальной мир) к серверу на этом порту.

Вам нужно будет добавить правило "Port Forwarding" к вашему модему / маршрутизатору, которое перенаправляет весь трафик на порт 12345 на локальный ip, где вы размещаете сервер (ip вашего компьютера; найден ipconfig или же ifconfig cmd в консоли / терминале). Тогда вам нужно будет получить ваш "Внешний IP", который можно найти с помощью Google "Что такое мой IP". Это "адрес" вашей сети для остального мира. Это IP, который вы должны дать своему другу.

Вашему другу необходимо использовать ваш внешний IP-адрес, который вы ему дали, а также порт, на котором работает сервер, и ваш маршрутизатор должен переадресовать свое соединение на ваш сервер и работать!

Некоторые темы, которые вы могли бы исследовать, еще: "Внешний IP-адрес против внутреннего IP-адреса" и "Переадресация портов".

Надеюсь это поможет!

Проблема в том, что вы пытаетесь получить доступ к компьютеру, который не имеет общедоступного IP-адреса. Единственный, что имеет "реальный" IP-адрес - это ваш маршрутизатор или кабельный модем (в зависимости от конфигурации). Чтобы удаленный компьютер имел доступ к компьютеру, на котором работает сервер, вам лучше всего настроить переадресацию портов для используемого вами порта сервера (12345) и убедитесь, что трафик перенаправляется на ваш компьютер.

Способы настройки переадресации портов различны для разных маршрутизаторов, вам придется погуглить свой роутер и фразу "переадресация портов". После того, как все настроено, клиент должен будет использовать публичный IP-адрес маршрутизатора (вы можете посмотреть это в настройках вашего маршрутизатора). Тогда это будет выглядеть следующим образом: клиент попадет в маршрутизатор, маршрутизатор перенаправит трафик на ваш локальный компьютер и сокет сервера, после чего он должен сделать это. После того, как соединение установлено, вы должны быть готовы.

Надеюсь, это поможет.

Другие вопросы по тегам