Java 信使套接字

标签 java sockets

我正在尝试制作一个“信使”(只是为了真正学习),并且对 Socket/ServerSocket 相当陌生,目前正致力于制作网络部分。 另外,我确实知道 ClientNetworking 并不完整。我试图完成它,但我被难住了。

服务器主:

public class ServerMain extends JFrame {

int WIDTH = 480;
int HEIGHT = 320;

String writeToConsole;

JPanel mainPanel, userPanel, consolePanel;
JTabbedPane tabbedPane;
JButton launchButton;
JTextArea console;
JTextField consoleInput;
JScrollPane consoleScroll;

public ServerMain() {
    super("Messenger Server");

    mainPanel = new JPanel();
    mainPanel.setLayout(null);

    Networking();
    createConsolePanel();

    userPanel = new JPanel();
    userPanel.setLayout(null);

    tabbedPane = new JTabbedPane();

    tabbedPane.add(mainPanel, "Main");
    tabbedPane.add(userPanel, "Users");
    tabbedPane.add(consolePanel, "Console");

    add(tabbedPane);
}

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

    } catch(UnsupportedLookAndFeelException e) {
        e.printStackTrace();

    } catch (ClassNotFoundException e) {
        e.printStackTrace();

    } catch (InstantiationException e) {
        e.printStackTrace();

    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

    ServerMain frame = new ServerMain();
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setSize(frame.WIDTH, frame.HEIGHT);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setResizable(false);
}

public void Networking() {
    ServerNetworking net;
    try {
        net = new ServerNetworking();
        net.start();
    } catch(Exception e) {
        e.printStackTrace();
    }
}

public void createConsolePanel() {
    consolePanel = new JPanel();
    consolePanel.setLayout(null);

    console = new JTextArea();
    console.setFont(new Font("", Font.PLAIN, 13 + 1/2));
    console.setBounds(0, 0, WIDTH, HEIGHT - 100);
    console.setEditable(false);
    console.setLineWrap(true);


    consoleInput = new JTextField(20);
    consoleInput.setBounds(0, 0, WIDTH, 25);
    consoleInput.setLocation(0, 240);
    consoleInput.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event) {
            String input = consoleInput.getText();

            if(input.equalsIgnoreCase("/sendmessage")) {
                //console.append(input);
                console.append("Input who you would like to send the message to:");
                consoleInput.setText("");

            } if (input.equalsIgnoreCase("/ban")) {
                console.append("Who you would like to ban");
                consoleInput.setText("");
            } 
        }
    });

    consolePanel.add(console);
    consolePanel.add(consoleInput);
}

public void consoleWrite(String write) {
    console.append(write);
}
}

服务器网络(线程):

public class ServerNetworking extends Thread {
private static ServerSocket servSock;
private static final int PORT = 1234;

private static void handleClient() {
    Socket link = null;                                 
    try {
        link = servSock.accept();                       

        Scanner input = new Scanner(link.getInputStream());     
        PrintWriter output =
        new PrintWriter(link.getOutputStream(),true);

        int numMessages = 0;
        String message = input.nextLine();
        while (!message.equals("***CLOSE***")) {
            System.out.println("Message received.");
            numMessages++;
            output.println("Message " +
            numMessages + ": " + message);
            message = input.nextLine();
        }
        output.println(numMessages + " messages received.");
    } catch(IOException ioEx)  {
        ioEx.printStackTrace();
    } finally {
        try {
            System.out.println( "\n* Closing connection... *");
            link.close();
        } catch(IOException ioEx) {
            System.out.println("Unable to disconnect!");
            System.exit(1);
        }
    }
}

public void run() {
     System.out.println("Opening port...\n");
     try {
         servSock = new ServerSocket(PORT);
     } catch(IOException ioEx) {
         System.out.println("Unable to attach to port!");
         System.exit(1);
     } do {
         handleClient();
     } while (true);
}

}

客户端主:

public class ClientMain extends JFrame {

int WIDTH = 640;
int HEIGHT = 480;

JTabbedPane tabbedPane;
JMenuBar topMenuBar;
JMenu userMenu, helpMenu, settingsMenu;
JRadioButtonMenuItem menuItem;
JPanel mainPanel, friendsPanel, groupsPanel, testPanel;
JLabel title;
JScrollPane consoleScrollPane;
JSplitPane friendsPane;
JTextArea messageArea, testArea;
JTextField testField;
Box box;

public ClientMain() {
    super("Messenger Client");

    Networking();

    title = new JLabel("Client!");
    title.setFont(new Font("Impact", Font.PLAIN, 32));

    mainPanel = new JPanel();
    mainPanel.setLayout(null);
    mainPanel.add(title);

    groupsPanel = new JPanel();
    groupsPanel.setLayout(null);

    friendsPanel = new JPanel();
    friendsPanel.setLayout(null);

    testPanel = new JPanel();
    testPanel.setLayout(null);

    testArea = new JTextArea();
    testArea.setFont(new Font("", Font.PLAIN, 13 + 1/2));
    testArea.setBounds(0, 0, WIDTH, HEIGHT - 100);
    testArea.setEditable(false);
    testArea.setLineWrap(true);

    testField = new JTextField(20);
    testField.setBounds(0, 380, 640, 25);
    //testField.setLocation(0, HEIGHT - 50);
    testField.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            ClientNet net = new ClientNet();
            String input = null;
            input = testField.getText();
            testArea.append(input);
            testField.setText("");

            if(input.equalsIgnoreCase("/sendmessage")) {
                testArea.append("\n Input who you would like to send the message to:");
                input = null;

                if(input.equalsIgnoreCase("Hello")) {
                    net.userEntry = input;
                }
            }
        }
    });

    testPanel.add(testArea);
    testPanel.add(testField);

    tabbedPane = new JTabbedPane();

    tabbedPane.add(mainPanel, "Main");
    tabbedPane.add(friendsPanel, "Friends");
    tabbedPane.add(groupsPanel, "Groups");
    tabbedPane.add(testPanel, "Test");

    topMenuBar = new JMenuBar();

    userMenu = new JMenu("User");

    settingsMenu = new JMenu("Settings");

    helpMenu = new JMenu("Help");

    menuItem = new JRadioButtonMenuItem("Something here");

    userMenu.add(menuItem);

    topMenuBar.add(userMenu, "User");
    topMenuBar.add(settingsMenu, "Settings");
    topMenuBar.add(helpMenu, "Help");

    add(topMenuBar);
    add(tabbedPane);
}

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

    } catch(UnsupportedLookAndFeelException e) {
        e.printStackTrace();

    } catch (ClassNotFoundException e) {
        e.printStackTrace();

    } catch (InstantiationException e) {
        e.printStackTrace();

    } catch (IllegalAccessException e) {
        e.printStackTrace();

    }

    ClientMain frame = new ClientMain();
    Insets insets = frame.getInsets();
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setSize(frame.WIDTH, frame.HEIGHT);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setJMenuBar(frame.topMenuBar);

}

public void Networking() {
    ClientNet net;
    try {
        net = new ClientNet();
        net.start();

    } catch(Exception e) {
        e.printStackTrace();
    }
}

public void createMenuBar() {
    topMenuBar = new JMenuBar();

    userMenu = new JMenu("User");
    settingsMenu = new JMenu("Settings");
    helpMenu = new JMenu("Help");

    menuItem = new JRadioButtonMenuItem("MenuItem");
    menuItem.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

        }
    });

    topMenuBar.add(userMenu, "User");
    topMenuBar.add(settingsMenu, "Settings");
    topMenuBar.add(helpMenu, "Help");
}

public void getFriends(String username) {

}

}

客户端网络(线程):

public class ClientMain extends JFrame {

int WIDTH = 640;
int HEIGHT = 480;

JTabbedPane tabbedPane;
JMenuBar topMenuBar;
JMenu userMenu, helpMenu, settingsMenu;
JRadioButtonMenuItem menuItem;
JPanel mainPanel, friendsPanel, groupsPanel, testPanel;
JLabel title;
JScrollPane consoleScrollPane;
JSplitPane friendsPane;
JTextArea messageArea, testArea;
JTextField testField;
Box box;

public ClientMain() {
    super("Messenger Client");

    Networking();

    title = new JLabel("Client!");
    title.setFont(new Font("Impact", Font.PLAIN, 32));

    mainPanel = new JPanel();
    mainPanel.setLayout(null);
    mainPanel.add(title);

    groupsPanel = new JPanel();
    groupsPanel.setLayout(null);

    friendsPanel = new JPanel();
    friendsPanel.setLayout(null);

    testPanel = new JPanel();
    testPanel.setLayout(null);

    testArea = new JTextArea();
    testArea.setFont(new Font("", Font.PLAIN, 13 + 1/2));
    testArea.setBounds(0, 0, WIDTH, HEIGHT - 100);
    testArea.setEditable(false);
    testArea.setLineWrap(true);

    testField = new JTextField(20);
    testField.setBounds(0, 380, 640, 25);
    //testField.setLocation(0, HEIGHT - 50);
    testField.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            ClientNet net = new ClientNet();
            String input = null;
            input = testField.getText();
            testArea.append(input);
            testField.setText("");

            if(input.equalsIgnoreCase("/sendmessage")) {
                testArea.append("\n Input who you would like to send the message to:");
                input = null;

                if(input.equalsIgnoreCase("Hello")) {
                    net.userEntry = input;
                }
            }
        }
    });

    testPanel.add(testArea);
    testPanel.add(testField);

    tabbedPane = new JTabbedPane();

    tabbedPane.add(mainPanel, "Main");
    tabbedPane.add(friendsPanel, "Friends");
    tabbedPane.add(groupsPanel, "Groups");
    tabbedPane.add(testPanel, "Test");

    topMenuBar = new JMenuBar();

    userMenu = new JMenu("User");

    settingsMenu = new JMenu("Settings");

    helpMenu = new JMenu("Help");

    menuItem = new JRadioButtonMenuItem("Something here");

    userMenu.add(menuItem);

    topMenuBar.add(userMenu, "User");
    topMenuBar.add(settingsMenu, "Settings");
    topMenuBar.add(helpMenu, "Help");

    add(topMenuBar);
    add(tabbedPane);
}

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

    } catch(UnsupportedLookAndFeelException e) {
        e.printStackTrace();

    } catch (ClassNotFoundException e) {
        e.printStackTrace();

    } catch (InstantiationException e) {
        e.printStackTrace();

    } catch (IllegalAccessException e) {
        e.printStackTrace();

    }

    ClientMain frame = new ClientMain();
    Insets insets = frame.getInsets();
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setSize(frame.WIDTH, frame.HEIGHT);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setJMenuBar(frame.topMenuBar);

}

public void Networking() {
    ClientNet net;
    try {
        net = new ClientNet();
        net.start();

    } catch(Exception e) {
        e.printStackTrace();
    }
}

public void createMenuBar() {
    topMenuBar = new JMenuBar();

    userMenu = new JMenu("User");
    settingsMenu = new JMenu("Settings");
    helpMenu = new JMenu("Help");

    menuItem = new JRadioButtonMenuItem("MenuItem");
    menuItem.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

        }
    });

    topMenuBar.add(userMenu, "User");
    topMenuBar.add(settingsMenu, "Settings");
    topMenuBar.add(helpMenu, "Help");
}

public void getFriends(String username) {

}
}

这是我启动服务器然后启动客户端时遇到的错误: 它不应该说“消息已收到”,因为我实际上没有发送消息

Opening port...

Message received.

* Closing connection... *
Exception in thread "Thread-1" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at Server.ServerNetworking.handleClient(ServerNetworking.java:29)
at Server.ServerNetworking.run(ServerNetworking.java:53)

最佳答案

我认为问题出在 ServerNetworking 类中的以下循环:

while (!message.equals("***CLOSE***")) {
    System.out.println("Message received.");
    numMessages++;
    output.println("Message " +
    numMessages + ": " + message);
    message = input.nextLine();
}

这段代码的问题在于从客户端收到完整的消息后最后一行代码

message = input.nextLine();

从消息中查找下一行,但由于该消息已被使用,因此会抛出以下异常:

NoSuchElementException - if no line was found 

因此,在读取下一行之前,您需要确保有下一行要读取。您可以使用

hasNextLine()

方法,如果有下一行则返回 true,否则返回 false。

if(input.hasNextLine()) {
    message = input.nextLine();  // read the next line
} else {
   break;  // exit the loop because, nothing to read left
}

关于Java 信使套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19662326/

相关文章:

java - 字符串文字的存储长度会对性能产生影响吗?

java - Jedis SpringBoot 无法序列化和反序列化 Map<String, Object>

java - maven-cargo2-plugin 如何识别我的 Spring Boot 应用程序已经运行了嵌入式 Tomcat?

sockets - 如何设置winsock的保活间隔

sockets - nginx、fastcgi 和开放套接字

android - 创建TCP套接字时无法识别Android主机名

java - 如何在spring mvc中将用户表单数据发送到服务器

java - 反序列化一个 ArrayList。没有有效的构造函数

服务器端的 Python 套接字错误编号 3

java - 如何在 Java SE 中使用 SSL 设置相互身份验证