Java套接字未连接到同一网络外部

时间:2015-08-19 10:04:11

标签: java sockets

您好我无法让服务器和客户端在不在同一网络上时相互连接。请问您能看一下代码,看看我需要做些什么来解决这个问题。

我是Java的新手,也是整个网络方面的事情,所以任何帮助都会受到赞赏。

服务器

>!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;


public class ChatServer {


private static final int PORT = 9001;


private static HashSet<String> names = new HashSet<String>();


private static HashSet<PrintWriter> writers = new HashSet<PrintWriter>();


public static void main(String[] args) throws Exception {
    System.out.println("The chat server is running.");
    ServerSocket listener = new ServerSocket(PORT);
    try {
        while (true) {
            new Handler(listener.accept()).start();
        }
    } finally {
        listener.close();
    }
}


private static class Handler extends Thread {
    private String name;
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;


    public Handler(Socket socket) {
        this.socket = socket;
    }


    @Override
    public void run() {
        try {

            // Create character streams for the socket.
            in = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);

            // Request a name from this client.  Keep requesting until
            // a name is submitted that is not already used.  Note that
            // checking for the existence of a name and adding the name
            // must be done while locking the set of names.
            while (true) {
                out.println("SUBMITNAME");
                name = in.readLine();
                if (name == null) {
                    return;
                }
                synchronized (names) {
                    if (!names.contains(name)) {
                        names.add(name);
                        break;
                    }
                }
            }

            // Now that a successful name has been chosen, add the
            // socket's print writer to the set of all writers so
            // this client can receive broadcast messages.
            out.println("NAMEACCEPTED");
            writers.add(out);

            // Accept messages from this client and broadcast them.
            // Ignore other clients that cannot be broadcasted to.
            while (true) {
                String input = in.readLine();
                if (input == null) {
                    return;
                }
                for (PrintWriter writer : writers) {
                    writer.println("MESSAGE " + name + ": " + input);
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        } finally {
            // This client is going down!  Remove its name and its print
            // writer from the sets, and close its socket.
            if (name != null) {
                names.remove(name);
            }
            if (out != null) {
                writers.remove(out);
            }
            try {
                socket.close();
            } catch (IOException e) {
            }
          }
       }
    }
 }

客户

>!   


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;


public class ChatClient {

BufferedReader in;
PrintWriter out;
JFrame frame = new JFrame("Messager");
JTextField textField = new JTextField(40);
JTextArea messageArea = new JTextArea(8, 40);


public ChatClient() {

    // Layout GUI
    textField.setEditable(false);
    messageArea.setEditable(false);
    frame.getContentPane().add(textField, "North");
    frame.getContentPane().add(new JScrollPane(messageArea), "Center");
    frame.pack();

    // Add Listeners
    textField.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            out.println(textField.getText());
            textField.setText("");
        }
    });
}

/**
 * Prompt for and return the address of the server.
 */
private String getServerAddress() {
    return JOptionPane.showInputDialog(
        frame,
        "Enter IP Address of the Server:",
        "Welcome to the Messager",
        JOptionPane.QUESTION_MESSAGE);
}

/**
 * Prompt for and return the desired screen name.
 */
private String getName() {
    return JOptionPane.showInputDialog(
        frame,
        "Choose a screen name:",
        "Screen name selection",
        JOptionPane.PLAIN_MESSAGE);
}

/**
 * Connects to the server then enters the processing loop.
 */
private void run() throws IOException {

    // Make connection and initialize streams
    String serverAddress = getServerAddress();
    Socket socket = new Socket("86.190.97.107", 9001);
    in = new BufferedReader(new InputStreamReader(
        socket.getInputStream()));
    out = new PrintWriter(socket.getOutputStream(), true);

    // Process all messages from server, according to the protocol.
    while (true) {
        String line = in.readLine();
        if (line.startsWith("SUBMITNAME")) {
            out.println(getName());
        } else if (line.startsWith("NAMEACCEPTED")) {
            textField.setEditable(true);
        } else if (line.startsWith("MESSAGE")) {
            messageArea.append(line.substring(8) + "\n");
        }
    }
}

/**
 * Runs the client as an application with a closeable frame.
 */
public static void main(String[] args) throws Exception {
    ChatClient client = new ChatClient();
    client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    client.frame.setVisible(true);
    client.run();
  }

}

1 个答案:

答案 0 :(得分:-1)

感谢您的所有答案,我发现服务器需要托管在单独的计算机上才能使外部IP正常工作。