【发布时间】:2015-01-13 00:07:03
【问题描述】:
我有一个运行 Java JDK 7“服务器”的 Linux Microsoft Azure VM(使用 SSH 连接)
我的电脑 (Mac OSX) 正在运行 Java JDK 8“服务器”
消息客户端在我的电脑上编译运行,服务器在我的vm上运行编译。我已将端口 xxx2 和 xxx3 配置为 UDP。
服务器代码:
public class server {
public static void main(String args[]) throws Exception {
int OutPort = xxx2;
int InPort = xxx3;
byte data[] = new byte[2048];
System.out.println("LOCALHOST:" + InetAddress.getLocalHost());
InetAddress users[] = new InetAddress[1000];
DatagramSocket dataIn = new DatagramSocket(OutPort);
DatagramSocket dataOut = new DatagramSocket(InPort);
DatagramPacket dataIncoming = new DatagramPacket(data, 2048);
int userNum = 0;
while (true) {
try {
dataIn.receive(dataIncoming);
} catch (IOException e) {
System.out.println(e);
}
String message = dataIncoming.getData().toString();
if (message.startsWith("login")) {
users[userNum] = dataIncoming.getAddress();
System.out.println("NEW USER:" + dataIncoming.getAddress().toString() + ", ADDED AS:" + users[userNum]);
userNum++;
}
for (int i = 0; i <= userNum; i++) {
dataOut.send(new DatagramPacket(message.getBytes(), 2048, users[i], InPort));
}
}
}
}
客户端代码:
public class message {
public String username;
public int OutPort = xxx2;
public int InPort = xxx3;
// xxx2 out, xxx3 in (default for testing the opposite).
final InetAddress address;
message() throws UnknownHostException {
// Create the variables.
InetAddress addresses[] = null;
address = InetAddress.getByName("xxxxx.cloudapp.net");
addresses = InetAddress.getAllByName("xxxxx.cloudapp.net");
// Create the colors.
Color background = new Color(141,234,184);
// Create the window.
JFrame window = new JFrame("Java Message");
window.setSize(600,400);
window.setLayout(new BorderLayout());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
// Create the title.
JLabel title = new JLabel("Xxxxx's Java Messaging System");
title.setFont(new Font("Arial", Font.PLAIN, 24));
title.setOpaque(true);
title.setBackground(background);
title.setHorizontalAlignment(SwingConstants.CENTER);
window.add(title, BorderLayout.NORTH);
// Create the text output.
JTextArea content = new JTextArea();
content.setFont(new Font("Arial", Font.PLAIN, 14));
content.setEditable(false);
window.add(content, BorderLayout.CENTER);
JScrollPane scroll = new JScrollPane(content);
window.add(scroll, BorderLayout.CENTER);
// Create the info panel.
JTextArea info = new JTextArea();
info.setFont(new Font("Menlo", Font.PLAIN, 14));
startup(info, address, addresses);
window.add(info, BorderLayout.EAST);
// Create username dialog.
JDialog usernameWindow = new JDialog();
usernameWindow.setTitle("Username setup");
usernameWindow.setSize(300,200);
usernameWindow.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
usernameWindow.setVisible(true);
// Create username title.
JLabel loginTitle = new JLabel("Enter a username:");
loginTitle.setFont(new Font("Arial", Font.PLAIN, 16));
usernameWindow.add(loginTitle, BorderLayout.CENTER);
// Create username input.
JTextField usernameInput = new JTextField();
usernameInput.setFont(new Font("Arial", Font.PLAIN, 16));
usernameWindow.add(usernameInput, BorderLayout.SOUTH);
usernameInput.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (usernameInput.getText().length() >= 8) {
errorDialog("Username too long, must be 8 characters or less!");
} else {
username = usernameInput.getText().toString().toUpperCase();
content.append(":Logged in as:" + username + "\n");
sendMessage("login", username, address);
usernameWindow.dispose();
}
}
});
// Create the text input.
JTextField messageInput = new JTextField();
window.add(messageInput, BorderLayout.SOUTH);
reciveMessages(content);
messageInput.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
sendMessage(username, messageInput.getText(), address);
messageInput.setText("");
}
});
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new message();
} catch (Exception e) {
System.out.println("ERROR:" + e);
}
}
});
}
public void startup(JTextArea content, InetAddress ip, InetAddress ips[]) {
InetAddress local = null;
try {
local = InetAddress.getLocalHost();
} catch(Exception e) {
System.out.println(e);
}
content.append("SERVER IP(s):\n");
for (int i = 0; i < ips.length; i++) content.append(ips[i].getHostAddress() + "\n");
content.append("USING:\n" + ip.getHostAddress() + "\n\n");
content.append("LOCALHOST:\n" + local.getHostAddress() + "\n");
}
public void sendMessage(String username, String message, InetAddress address) {
byte data[] = new byte[2048];
char usernameChar[] = username.toCharArray();
char messageChar[] = message.toCharArray();
for (int i = 0; i < usernameChar.length; i++) data[i] = (byte)usernameChar[i];
data[usernameChar.length + 1] = (byte)':';
for (int c = 0; c < messageChar.length; c++) data[usernameChar.length + c + 2] = (byte)messageChar[c];
try {
DatagramSocket outSocket = new DatagramSocket(OutPort);
DatagramPacket dataOut = new DatagramPacket(data, 2048, address, InPort);
outSocket.send(dataOut);
} catch (Exception e) {
System.out.println(e);
}
}
public void reciveMessages(JTextArea content) {
new Thread("PortListener") {
public void run() {
try {
byte inData[] = new byte[2048];
DatagramSocket inSocket = new DatagramSocket(InPort);
DatagramPacket dataIn = new DatagramPacket(inData, 2048);
while (true) {
inSocket.receive(dataIn);
content.append(new String(dataIn.getData(), 0, dataIn.getLength()));
}
} catch (Exception e) {
System.out.println(e);
}
}
}.start();
}
public void errorDialog(String cause) {
}
}
问题:我在 VM 上运行服务器代码,控制台从不返回“新用户:”,并且没有任何消息通过。
我对 Java 网络完全陌生,是在完成 Java 指南章节(该书由 Oracle 出版)后完成的,我需要一些有关如何使其工作的指导。
我不知道这是一个简单的错误还是整个想法和理论都是错误的。
我的理论:
服务器错误地监听数据包。
客户端和服务器数据[]大小不同。
服务器的 IP 地址不正确(例如:缺少内部 IP),我需要使用 SocketAddress。
我知道的:
我已经制作了这个程序的一个版本,我在其中编译了它,然后在切换端口的情况下重新编译它(所以传出变成了传入数据)并在我的计算机上运行并且系统运行良好。
【问题讨论】:
-
我一直在使用 java,因为我还在上高中,还没有在电脑前那么忙。所以请原谅我的愚蠢或简单的错误。
-
您的服务器检查数据报是否以“登录”开头。你发送的数据报不是以“login”开头的。
-
@immibis 一旦用户创建了他们的用户名,系统就会发送一条以“login”开头的消息(参见 ln 83)
标签: java azure udp port datagram