0

一段时间以来,我一直在仅使用 Java 代码开发即时通讯工具。只有当我在同一台计算机上运行服务器和客户端然后它们进行通信时,我才能让它工作。但我无法让 2 台不同的计算机连接到同一台服务器并进行通信。我看了很多例子,但我仍然不明白需要改变什么。我将在下面显示大部分代码,其中大部分可以忽略,只需要查看网络部分。服务器连接位于客户端代码的底部。我是初学者,我很感激任何帮助。谢谢。

客户代码:

import javax.swing.*;
import javax.swing.text.DefaultCaret;

import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.Date;
import java.net.*;
import java.io.*;



public class NukeChatv3 extends JFrame
{

private JTextArea showtext;
private JTextField usertext;
private String hostname;
private Socket connectionsock;
private BufferedReader serverinput;
private PrintWriter serveroutput;
private int port;


private static final long serialVersionUID = 1L;

private class entersend implements KeyListener
{
      public void keyTyped ( KeyEvent e )
      {  

      }  
      public void keyPressed ( KeyEvent e)
      {  
          String text = usertext.getText();

          if(e.getKeyCode()== KeyEvent.VK_ENTER)
          {
              if (usertext.getText().equals(""))
                    return;
                else
                {
                    //try{
                    serveroutput.println(text);

                    usertext.setText("");
                    //showtext.append("[" + ft.format(dNow) + "]" + "\n" + "UserName: " + serverdata +"\n\n");
                    //}
                    /*catch(IOException in)
                    {
                        showtext.append(in.getMessage());
                    }*/

                }
          }
          else 
              return;
      }  
      public void keyReleased ( KeyEvent e )
      {  

      } 
}

private class sender implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        if (usertext.getText().equals(""))
            return;
        else
        {
            Date dNow = new Date( );
            SimpleDateFormat ft = new SimpleDateFormat ("hh:mm:ss");
            String text = usertext.getText();
            usertext.setText("");

            //* Send message to server



            showtext.append(ft.format(dNow) + "\n" + "UserName: " + text +"\n\n");
        }
    }
}

private class startconnection implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        clientconnection connect = new clientconnection();
        connect.start();
    }
}

private class CheckOnExit implements WindowListener
{
    public void windowOpened(WindowEvent e)
    {}

    public void windowClosing(WindowEvent e)
    {
        ConfirmWindow checkers = new ConfirmWindow( );
        checkers.setVisible(true);
    }

    public void windowClosed(WindowEvent e)
    {}

    public void windowIconified(WindowEvent e)
    {}

     public void windowDeiconified(WindowEvent e)
    {}

    public void windowActivated(WindowEvent e)
    {}

    public void windowDeactivated(WindowEvent e)
    {}
}


private class ConfirmWindow extends JFrame implements ActionListener
{

    private static final long serialVersionUID = 1L;

    public ConfirmWindow( )
    {
        setSize(200, 100);
        getContentPane( ).setBackground(Color.LIGHT_GRAY);
        setLayout(new BorderLayout( ));

        JLabel confirmLabel = new JLabel(
                       "Are you sure you want to exit?");
        add(confirmLabel, BorderLayout.CENTER);

        JPanel buttonPanel = new JPanel( );
        buttonPanel.setBackground(Color.GRAY);
        buttonPanel.setLayout(new FlowLayout( ));

        JButton exitButton = new JButton("Yes");
        exitButton.addActionListener(this);
        buttonPanel.add(exitButton);

        JButton cancelButton = new JButton("No");
        cancelButton.addActionListener(this);
        buttonPanel.add(cancelButton);

        add(buttonPanel, BorderLayout.SOUTH);
    }

    public void actionPerformed(ActionEvent e) 
    {
        String actionCommand = e.getActionCommand( );

        if (actionCommand.equals("Yes")) 
            System.exit(0);
        else if (actionCommand.equals("No"))
            dispose( );
        else
            System.out.println("Unexpected Error in Confirm Window.");
    }
}


public static void main(String[] args) 
{

    NukeChatv3 nuke = new NukeChatv3();
    nuke.setVisible(true);

}

public NukeChatv3()
{       
        setTitle("NukeChat v3");
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        setSize(550, 400);
        setResizable(false);
        addWindowListener(new CheckOnExit());
        addWindowListener(new WindowAdapter(){
            public void windowOpened(WindowEvent e){
                usertext.requestFocus();
            }
        });
        getContentPane().setBackground(Color.BLACK);
        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();

        showtext = new JTextArea(15, 35);
        showtext.setEditable(false);
        showtext.setLineWrap(true);
        DefaultCaret caret = (DefaultCaret)showtext.getCaret();
        caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);


        JScrollPane scrollbar = new JScrollPane(showtext);
        scrollbar.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrollbar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        c.anchor = GridBagConstraints.FIRST_LINE_START;
        //c.gridwidth = 2;
        c.insets = new Insets(20, 20, 20, 20);
        c.weightx = .5;
        c.weighty = .5;
        c.gridx = 0;
        c.gridy = 0;
        add(scrollbar, c);

        usertext = new JTextField(35);

        usertext.requestFocusInWindow();
        usertext.addKeyListener(new entersend());
        //c.gridwidth = 1;
        c.insets = new Insets(0, 20, 0, 0);
        c.weightx = .5;
        c.gridx = 0;
        c.gridy = 1;
        add(usertext, c);

        JPanel empty = new JPanel();
        c.gridx = 1;
        c.gridy = 0;
        empty.setLayout(new GridLayout(2,1));

        JButton test1 = new JButton("test1");
        empty.add(test1);

        JButton test2 = new JButton("test2");
        empty.add(test2);

        add(empty, c);

        JButton send = new JButton("Send");
        send.addActionListener(new sender());
        c.ipady = -5;
        c.insets = new Insets(0, 0, 20, 0);
        c.gridx = 1;
        c.gridy = 1;
        add(send, c);

        JMenu menu = new JMenu("File");
        JMenuItem connection = new JMenuItem("Connect");
        connection.addActionListener(new startconnection());
        menu.add(connection);

        JMenuBar bar = new JMenuBar();
        bar.add(menu);
        setJMenuBar(bar);



}

private class clientconnection  extends Thread
{
    public void run()
    {
        try
        {
            // Set host name and port//
            hostname = "localhost";
            port = 16666;

            // connect to socket of the server//
            connectionsock = new Socket(hostname, port);

            // set up client input from server//
            serverinput = new BufferedReader(new InputStreamReader(connectionsock.getInputStream()));

            // set up client output to server//
            serveroutput = new PrintWriter(connectionsock.getOutputStream(), true);

            // set up a looping thread to constantly check if server has sent anything 
            String serverdata = "";

            while ((serverdata = serverinput.readLine()) != null)
            {
                Thread.sleep(500);
                Date dNow = new Date( );
                SimpleDateFormat ft = new SimpleDateFormat ("hh:mm:ss");
                showtext.append("[" + ft.format(dNow) + "]" + "\n" +"Recieved from server: \n" + "UserName: " + serverdata +"\n\n");
            }

        }

        catch(IOException e)
        {
            System.out.println(e.getMessage());
        }
        catch(InterruptedException inter)
        {
            showtext.append("Unexpected interruption\n\n");
        }
    }


}

}

服务器代码:

import java.net.ServerSocket;
import java.io.*;
import java.net.Socket;
import java.io.DataOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;



public class servertest extends JFrame
{

private JButton start;
private JTextArea text;
private BufferedReader clientinput;
private PrintWriter clientoutput;

private class listen implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        connection connect = new connection();
        connect.start();
    }
}

public servertest ()
{
    setSize(400,300);
    setLayout(new BorderLayout());
    start = new JButton("Start");
    start.addActionListener(new listen());
    add(start, BorderLayout.SOUTH);

    text = new JTextArea(6, 10);
    text.setEditable(false);
    add(text, BorderLayout.CENTER);
}
private class connection extends Thread
{
    public void run()
    {
    try
    {
        // Sets up a server socket with set port//
        text.setText("Waiting for connection on port 16666");
        ServerSocket serversock = new ServerSocket(16666);

        // Waits for the Client to connect to the server//
        Socket connectionsock = serversock.accept();

        // Sets up Input from the Client to go to the server//
        clientinput = new BufferedReader(new InputStreamReader(connectionsock.getInputStream()));

        // Sets up data output to send data from server to client//
        clientoutput = new PrintWriter(connectionsock.getOutputStream(), true);

        // Test server to see if it can perform a simple task//
        text.setText("Connection made, waiting to client to send there name");
        clientoutput.println("Enter your name please.");

        // Get users name//
        String clienttext = clientinput.readLine();

        // Reply back to the client//
        String replytext = "Welcome " + clienttext;
        clientoutput.println(replytext);
        text.setText("Sent: " + replytext);

        while ((replytext = clientinput.readLine()) != null)
        {
            clientoutput.println(replytext);
            text.setText("Sent: " + replytext);
        }

        // If you need to close the Socket connections
        // clientoutput.close();
        // clientinput.close();
        // connetionsock.close();
        // serversock.close();

    }

    catch(IOException e)
    {
        System.out.println(e.getMessage());
    }
    }
}

public static void main(String[] args)
{
    servertest test = new servertest();
    test.setVisible(true);
}
4

1 回答 1

1

在您的客户端代码中,指定服务器正在运行的正确主机名/IP 地址:

private class clientconnection  extends Thread
{
    public void run()
    {
        try
        {
            // Set host name and port//
            hostname = "localhost"; //<---- Change this to server IP address
            port = 16666;
于 2013-01-21T05:00:47.017 回答