Простая программа сервера / клиента получает ошибку: 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-адрес маршрутизатора (вы можете посмотреть это в настройках вашего маршрутизатора). Тогда это будет выглядеть следующим образом: клиент попадет в маршрутизатор, маршрутизатор перенаправит трафик на ваш локальный компьютер и сокет сервера, после чего он должен сделать это. После того, как соединение установлено, вы должны быть готовы.
Надеюсь, это поможет.