在自己写的一个用TCP/IP连接的通信程序里面(一个客户端,一个服务器端),在自己电脑上调试的时候能运行(即两边都能收大数据),但是为什么放到别的电脑上就连接不到服务器了呢?这里所谓的别的电脑是指不跟自己电脑在同一个局域网内的,因为自己试过在朋友电脑(跟我电脑插在同一个交换机)上也可以进行通讯,不知道这是怎么回事啊?请大家帮帮忙嘛    我尝试了使用Socket clientSocket = new Socket(InetAddress.getByName(SERVER_ADDRESS),SERVER_PORT);
SERVER_ADDRESS的值既使用过服务器程序运行的电脑上的IP地址,也使用过电脑上"完整的计算机名",但是客户端在其他电脑(非局域网)上就是连不到服务器...急啊!

解决方案 »

  1.   

    端口是一样的,因为在自己电脑上都可以用,我所谓的非局域网:我想弄成像QQ那种在连个城市里也可以通讯,结果现在变成要在一个交换机(或者路由器)上才行...还有才看到的一个问题是我的运行服务器程序的电脑用的IP好象是自动分配的,并且是在学校里的网络.干脆我把程序贴上来,有兴趣的朋友帮帮忙吧!///////////////
    //////
    //////    Client.java
    //////import java.io.*;
    import java.net.*;import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    public class Client extends JFrame {
    private JTextField inputField;
    private JTextArea  showArea;
    private ObjectOutputStream output;
    private ObjectInputStream  input;
    private Socket client;
    private String message = "";
    private String chatServer;

    public Client(String host){
    super("Client!");

    chatServer = host;

    Container con = this.getContentPane();
    con.setLayout(new BorderLayout());

    inputField = new JTextField();
    inputField.setEnabled(false);

    inputField.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
    sendData(e.getActionCommand());
    }
    });

    con.add(inputField,BorderLayout.SOUTH);

    showArea = new JTextArea();
    showArea.setEditable(false);
    con.add(new JScrollPane(showArea),BorderLayout.CENTER);

    this.setSize(300,150);
    this.setVisible(true);
    }

    public void runClient(){
    try{
    connectToServer();

    getStream();

    processConnection();

    closeConnection();
    }
    catch(EOFException eofe)
    {
    System.out.println("Client terminated connection!");
    }
    catch(IOException ioe)
    {
    ioe.printStackTrace();
    }
    }

    private void getStream() throws IOException{
    output = new ObjectOutputStream(client.getOutputStream());

    output.flush();

    input = new ObjectInputStream(client.getInputStream());

    showArea.append("\nGot I/O streams!\n");
    }

    private void connectToServer() throws IOException{
    showArea.setText("Attempting connection!");

    client = new Socket(InetAddress.getByName(chatServer),5127);

    showArea.append("Connect to: " + 
    client.getInetAddress().getHostName());
    } private void processConnection() throws IOException{
    inputField.setEnabled(true);

    do{
    try{
    message = (String)input.readObject();
    showArea.append("\n" + message);
    showArea.setCaretPosition(showArea.getText().length());
    }
    catch(ClassNotFoundException e){
    showArea.append("\nUnknown object type received");
    }
    }while(!message.equals("SERVER>>> TERMINATE"));
    } private void closeConnection() throws IOException{
    showArea.append("\nClosing connection!");
    output.close();
    input.close();
    client.close();
    } private void sendData(String message){
    try{
    output.writeObject("CLIENT>>> " + message);
    output.flush();
    showArea.append("\nCLIENT>>> " + message);
    inputField.setText("");
    }
    catch(IOException e){
    showArea.append("\nError writing object!");
    }
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO 自动生成方法存根
    Client client;
    if(args.length == 0)
    client = new Client("192.168.1.24");
    //client = new Client("127.0.0.1");
    else
    client = new Client(args[0]);

    client.runClient();
    client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }}///////////////
    //////
    //////    Server.java
    //////import javax.swing.JFrame;
    import javax.swing.*;
    //import javax.swing.event.*;
    import java.io.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.net.*;
    public class Server extends JFrame {
    private JTextField inputField;
    private JTextArea  showArea;
    private ObjectOutputStream output;
    private ObjectInputStream  input;
    private ServerSocket server;
    private Socket connection;
    private int counter = 1;

    public Server(){
    super("Server !");

    Container con = this.getContentPane();
    con.setLayout(new BorderLayout());

    inputField = new JTextField();
    inputField.setEditable(false);

    inputField.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
    sendData(e.getActionCommand());
    }
    });

    con.add(inputField,BorderLayout.SOUTH);

    showArea = new JTextArea();
    showArea.setEditable(false);

    con.add(new JScrollPane(showArea),BorderLayout.CENTER);

    this.setSize(300,150);
    this.setVisible(true);
    }

    public void runServer()
    {
    try{
    server = new ServerSocket(5127,100);

    while(true){
    waitForConnection();

    getStream();

    processConnection();

    closeConnection();

    ++counter;
    }
    }
    catch(EOFException eofe)
    {
    System.out.println("Client terminated connection!");
    }
    catch(IOException ioe)
    {
    ioe.printStackTrace();
    }
    }

    private void waitForConnection() throws IOException{
    showArea.setText("Waiting for connection!\n");

    connection = server.accept();

    showArea.append("connection" + counter + "received from: " + 
    connection.getInetAddress().getHostName());
    }

    private void getStream() throws IOException{
    output = new ObjectOutputStream(connection.getOutputStream());

    output.flush();

    input = new ObjectInputStream(connection.getInputStream());

    showArea.append("\nGot I/O streams!\n");
    }

    private void processConnection() throws IOException{
    String message = "SERVER>>> Connection successful";
    output.writeObject(message);
    output.flush();

    inputField.setEnabled(true);
    inputField.setEditable(true);

    do{
    try{
    message = (String)input.readObject();
    showArea.append("\n" + message);
    showArea.setCaretPosition(showArea.getText().length());
    }
    catch(ClassNotFoundException e){
    showArea.append("\nUnkown object type received!");
    }
    }while(!message.equals("CLIENT>>> TERMINATE"));
    }

    private void closeConnection() throws IOException{
    showArea.append("\nUser Terminated connection!");
    inputField.setEnabled(false);
    output.close();
    input.close();
    connection.close();
    }

    private void sendData(String message){
    try{
    output.writeObject("SERVER>>> " + message);
    output.flush();
    showArea.append("\nSERVER>>> " + message);
    }
    catch(IOException e)
    {
    showArea.append("\nError writing object!");
    }
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO 自动生成方法存根
    Server server = new Server();

    server.runServer();

    server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }}
      

  2.   

    首先确认一点,服务端所在的机器是否是固定ip。根据你的描述,很可能已经通过nat协议给你转换过了,如果这样的话,那这台机器做为服务端几乎是不可能了,除非通过特殊手段。
    程序既然在局域网内能运行,在外网中那也问题不大。你可以找台带外网ip的机器试试,我猜测肯定会成功的。
      

  3.   

    这样说吧,7楼的朋友,我的IP是用的实验室的,是自动获取的.至于是不是你说的nat协议转换过了我就不知道了,不过为什么用那个协议转化过了就不行了呢!没怎么听到说过呢...还有,上次试验的时候我是跟我另外一个实验室的朋友一起试验的,但是很意外的发现我跟他的IP是一模一样的,在cmd下用ipconfig看到的,只是我跟他的子网掩码不一样而已...IP不是应该唯一确定吗!!!小弟不才,希望大侠们帮忙解惑.谢谢了!
      

  4.   

    因为你们都是在局域网内,所以你们的IP地址是可能会一样的
    IP地址只是在外网中是唯一的,所以你的代码是不可能直接连接到另外一个局域网中的机器
    如果你想实现这个功能,你需要判断自己是否在局域网中,如果是则通过协议要求网关打开映射端口才行
      

  5.   


    您的意思是:A作为服务器(存在于局域网中),这样一来其他局域网的电脑就连接不上来了是不是?而和A处于同一个局域网内的就可以连接到A上!如果上面A服务器的情况就是这样,那么我其他局域网的PC怎么才可以连到A,是需要在客户端编程还是在A服务器方?通过协议要求网关打开映射端口该如何用代码实现呢!我用的是java,在学习网络编程序,不知道有怎么复杂,初级的问题比较多,请知道的朋友能多多指点江山.
      

  6.   

    BBS:不知道不结贴可不可以给解决了我问题的朋友加分呢?我对加分的机制不是很清楚!
      

  7.   

    我说说我的理解吧,当然我网络学得相当的烂,也不是干这行的,可能也不太对,呵呵。
    首先,ip是唯一的,这点是正确的。但是ip是有限的,还分什么a类b类c类啥的,这应该知道吧,大部分ip资源都被美国占用着,现在据说ip地址应该很紧张了,所以才要搞什么ipv6,最热心的就是中国和日本,美国并不着急,因为他们国家的资源有的是。这个是上学时一个清华大学去我们学校讲座时说的,呵呵。
    ip地址不够怎么办呢?人们想出来了一个办法,组建一个局域网时,ip地址你随便定,插起门来当皇上,没人管你。然后统一给你这个局域网分配一个ip地址。当你访问外网时,网关会自动把你发送的数据包的局域网的ip地址变成那个统一的ip地址,并记录这个数据包的端口号。当有响应数据包回来时,把端口号取出来对比,如过端口号和你发送时的相匹配,在把统一的ip转换为你局域网中的ip,传说中的nat协议,可能大概奇就是这意思吧,当然我这比较朴素了,完全通过想象,没有研究过。所以对外边的机器来说,你的局域网是透明的,换句话说,外网机器不知道你是局域网,它认为仅仅是一台普通的主机。
    所以问题来了,如果你在局域网内的一台机器a上监听端口的话,有外部数据来的话,网关怎么知道把数据转发
    给a呢,如国网关没有经过特殊设置的话。
    所以,你一直问的问题已经超出了程序能解决之外了。qq之所以两个局域网内能够自由通讯,首要一点是他有固定的服务器。
      

  8.   

    ilovemeimei 跟 ChDw ,很感谢你们的帮忙呢~这让我对这方面又了解了不小,刚才去网上差了半天,确实跟你们说的情况是一样的,是我想的太简单了!也就是说程序照写没关系,只是到时候设置一下端口映射就可以监听了吧!谢谢哈,不过给分能不能都给呢~^_^!