目标:一个简单的应用程序,将客户端连接到一台计算机上托管的服务器,并允许该客户端从另一台计算机向该指定服务器上的所有人发送聊天消息。
Class ClientWindow:运行一个应用程序,提示用户输入服务器ID和端口。输入后,它将启动聊天程序。
出于某种我不知道的原因,聊天程序仅在连接到您在自己的计算机上创建的服务器时才起作用。来自其他计算机的其他客户端无法连接到该服务器。
可能的原因:
这里是聊天程序的代码。
此类在指定端口上启动服务器。 (在这种情况下为12348)
package server;
public class ChatServer {
public static void main(String[] args) {
// TODO Auto-generated method stub
Server.start(12348);
}
}
这是创建服务器并侦听客户端连接和消息的类。
package server;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
public class Server {
private static DatagramSocket socket;
private static boolean running;
private static int ClientID; // Ensures that no two users have the same client ID
private static ArrayList<ClientInfo> clients = new ArrayList<ClientInfo>();
public static void start(int port) {
try {
socket = new DatagramSocket(port);
System.out.println("Application Starting...");
running = true;
listen();
System.out.println("Server started on port: " + port);
} catch (Exception e) {
System.out.println("Failed somewhere");
e.printStackTrace();
}
}
private static void broadcast(String message) {
for (ClientInfo info : clients) {
send(message, info.getAddress(), info.getPort());
}
}
private static void send(String message, InetAddress address, int port) {
try {
message += "\\e";
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
System.out.println("Sent message to," + address.getHostAddress() + ":" + port);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void listen() {
Thread listenThread = new Thread("ChatProgram Listener Thread") {
public void run() {
try {
while(running) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
String message = new String(data);
//Identify where the end of the message is
message = message.substring(0, message.indexOf("\\e"));
//Manage message
if(!isCommand(message, packet)) {
broadcast(message);
}
}
} catch(Exception e){
e.printStackTrace();
}
}
}; listenThread.start();
}
/*
* SERVER COMMAND LIST
* \con:[name] -> Connects client to server
* \dis:[id] -> Disconnects client from server
*
*
*
*/
private static boolean isCommand(String message, DatagramPacket packet) {
if (message.startsWith("\\con:")) {
// RUN CONNECTION CODE
String name = message.substring(message.indexOf(":") + 1);
clients.add(new ClientInfo(name, ClientID++, packet.getAddress(), packet.getPort()));
broadcast("User " + name + " Connected!");
return true;
}
if (message.startsWith("\\dis:")) {
// RUN DISCONNECTION CODE
return true;
}
return false;
}
public static void stop() {
running = false;
}
}
启动客户端应用程序。
package client;
import java.awt.EventQueue;
import java.awt.Frame;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.awt.event.ActionEvent;
public class ClientWindow {
private JFrame frmChatProgram;
private JTextField textField;
private static JTextArea textArea = new JTextArea();
private Client client;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
ClientWindow window = new ClientWindow();
window.frmChatProgram.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ClientWindow() throws UnknownHostException {
initialize();
String name = JOptionPane.showInputDialog("Enter name:");
String servIp = JOptionPane.showInputDialog("Enter server IP address:");
String port = JOptionPane.showInputDialog("Enter server port:");
int parsedPort = Integer.parseInt(port);
//InetAddress inetAddress = InetAddress.getLocalHost();
client = new Client(name, servIp, parsedPort);
}
private void initialize() {
frmChatProgram = new JFrame();
frmChatProgram.setResizable(false);
frmChatProgram.setTitle("Chat Program");
frmChatProgram.setBounds(100, 100, 620, 446);
frmChatProgram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmChatProgram.setBackground(Color.WHITE);
frmChatProgram.getContentPane().setBackground(Color.DARK_GRAY);
frmChatProgram.getContentPane().setLayout(new BorderLayout(0, 0));
textArea.setForeground(Color.WHITE);
textArea.setBackground(Color.DARK_GRAY);
JScrollPane scrollPane = new JScrollPane(textArea);
frmChatProgram.getContentPane().add(scrollPane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.setBackground(Color.GRAY);
frmChatProgram.getContentPane().add(panel, BorderLayout.SOUTH);
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
textField = new JTextField();
textField.setBackground(Color.WHITE);
panel.add(textField);
textField.setColumns(40);
JButton btnNewButton = new JButton("Send");
btnNewButton.addActionListener(e ->{
if (!textField.getText().equals("")) {
client.send(textField.getText());
textField.setText("");
}
});
panel.add(btnNewButton);
frmChatProgram.setLocationRelativeTo(null);
}
public static void printToConsole(String message) {
textArea.setText(textArea.getText() + message + "\n");
}
}
为该客户端创建客户端连接和侦听器
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import server.ClientInfo;
public class Client {
private DatagramSocket socket;
private InetAddress address;
private int port;
private boolean running;
private String name;
public Client(String name, String address, int port) {
try {
this.name = name;
this.address = InetAddress.getByName(address);
this.port = port;
socket = new DatagramSocket();
socket.connect(this.address, port);
running = true;
listen();
send("\\con:" + name);
} catch (Exception e) {
e.printStackTrace();
}
}
public void send(String message) {
try {
if (!message.startsWith("\\")) {
message = name+": "+message;
}
message += "\\e";
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
System.out.println("Sent message to," + address.getHostAddress() + ":" + port);
} catch (Exception e) {
e.printStackTrace();
}
}
private void listen() {
Thread listenThread = new Thread("ChatProgram Listener Thread") {
public void run() {
try {
while (running) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
String message = new String(data);
// Identify where the end of the message is
message = message.substring(0, message.indexOf("\\e"));
// Manage message
if (!isCommand(message, packet)) {
ClientWindow.printToConsole(message);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}; listenThread.start();
}
private static boolean isCommand(String message, DatagramPacket packet) {
if (message.startsWith("\\con:")) {
// RUN CONNECTION CODE
return true;
}
if (message.startsWith("\\dis:")) {
// RUN DISCONNECTION CODE
return true;
}
return false;
}
}
我假设您正在询问代码无法正常工作的可能原因:
1)我可能错误地构造了服务器的接收/发送套接字。
这是可能的。通过使用调试器检查服务器端的数据包,您应该能够知道这一点。
2)我可能错误地构造了客户端的接收/发送套接字
同上...
3)客户端和服务器之间发送的数据包中有些异常
这是最有可能的:
4)以某种方式错误地定义了套接字的IP地址
有可能。
您可以采取各种措施来诊断/消除各种可能性。但这实际上不是StackOverflow问题。