我最近开始创建一个2D侧滚动游戏,仅使用Mac OSX Mavericks的java 7库,当我进入多人游戏时,我能够为我的游戏创建客户端和服务器处理程序,并且它们在客户端将数据发送到'localhost'但是当我使用我的外部IP时,服务器永远不会收到数据,我认为客户端的问题是当客户端被告知发送到'localhost'而不是我的外部IP时它是有效的,我有端口转发服务器的端口和本地IP,我的Mac的防火墙被禁用。在Java 7或Mac上是否存在UDP数据报套接字问题?
ClientHandler.java
package com.diedericksclan.main.network;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import com.diedericksclan.main.gui.*;
import com.diedericksclan.main.network.handling.Packet;
import com.diedericksclan.main.network.handling.PacketDisconnect;
import com.diedericksclan.main.network.handling.PacketLogin;
import com.diedericksclan.main.network.handling.PacketMovement;
import com.diedericksclan.main.network.handling.PlayerMP;
import com.diedericksclan.main.network.handling.Packet.PacketType;
public class ClientHandler extends Thread {
private InetAddress IPaddress;
private DatagramSocket dataSocket;
private DisplayHandler game;
public static boolean connected = false;
private int serverPort = 2048;
private int port;
public ClientHandler(DisplayHandler game, String ipaddress, int serverPort) {
this.game = game;
this.serverPort = serverPort;
try {
this.dataSocket = new DatagramSocket();
this.IPaddress = InetAddress.getByName(ipaddress);
this.port = dataSocket.getPort();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
public void callHost()
{
this.sendByteData("-3".getBytes());
}
public void run() {
while (true) {
byte[] gameData = new byte[8192];
DatagramPacket in = new DatagramPacket(gameData, gameData.length);
try {
this.dataSocket.receive(in);
} catch (IOException e) {
e.printStackTrace();
}
this.parsePacket(in.getData(), in.getAddress(), in.getPort());
}
}
private void parsePacket(byte[] data, InetAddress address, int port) {
String dataString = new String(data).trim();
System.out.println("Server[" + address.getHostAddress() + ":" + port + "] Data Recived: " + dataString);
PacketType type = Packet.lookupPacket(dataString.substring(0, 2));
Packet packet = null;
switch (type) {
default:
break;
case CONNECT:
this.connected = true;
break;
case SHUTDOWN:
this.game.setCurrentDisplay(this.game.dispMMenu);
this.game.dispGame.getEntities().clear();
this.connected = false;
break;
case INVALID:
break;
case LOGIN:
packet = new PacketLogin(data);
System.out.println("[" + address.getHostAddress() + ":" + Integer.toString(port) + "] " + ((PacketLogin)packet).getUsername() + " - Has just logged onto the server!");
PlayerMP playerLogin = new PlayerMP(game, ((PacketLogin)packet).getUsername(), address, port);
this.game.dispGame.getEntities().add(playerLogin);
break;
case DISCONNECT:
packet = new PacketDisconnect(data);
System.out.println("[" + address.getHostAddress() + ":" + Integer.toString(port) + "] " + ((PacketDisconnect)packet).getUsername() + " - Has just disconnected from the server!");
int index = this.game.dispGame.getEntityIndex(((PacketDisconnect)packet).getUsername());
this.game.dispGame.removePlayer(((PacketDisconnect)packet).getUsername());
if(this.game.dispGame.getEntities().get(index).getUsername() == ((PacketDisconnect)packet).getUsername()) {
this.game.dispGame.removePlayer(((PacketDisconnect)packet).getUsername());
}
this.connected = false;
break;
case MOVEMENT:
packet = new PacketMovement(data);
for(PlayerMP p : this.game.dispGame.getEntities()) {
if(p.getUsername().equals(((PacketMovement)packet).getUsername())) {
p.setX(((PacketMovement)packet).getX());
}
}
break;
}
}
public void sendByteData(byte[] data) {
DatagramPacket out = new DatagramPacket(data, data.length, this.IPaddress, this.serverPort);
try {
this.dataSocket.send(out);
System.out.println("Sending byte[] data to ServerHandler(" + out.getAddress().getHostAddress() + ":" + out.getPort() + ") From: " + InetAddress.getByName("localhost").getHostAddress() + ":" + this.dataSocket.getLocalPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
ServerHandler.java
package com.diedericksclan.main.network;
import java.io.IOException;
import java.net.*;
import java.util.*;
import com.diedericksclan.main.gui.*;
import com.diedericksclan.main.network.handling.*;
import com.diedericksclan.main.network.handling.Packet.*;
import com.diedericksclan.main.network.handling.*;
import com.diedericksclan.main.recource.*;
public class ServerHandler extends Thread {
private DatagramSocket dataSocket;
private DisplayHandler game;
public List<PlayerMP> players = new ArrayList<PlayerMP>();
public ServerHandler(DisplayHandler game, int port) {
this.game = game;
try {
this.dataSocket = new DatagramSocket(port, InetAddress.getByName("192.168.1.2"));
System.out.println(this.dataSocket.getInetAddress().getHostAddress() + ":" + port + " === " + this.dataSocket.getLocalAddress().getHostAddress() + ":" + port);
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
public void run() {
System.out.println("made");
while (true) {
byte[] data = new byte[8192];
DatagramPacket packet = new DatagramPacket(data, data.length);
try {
dataSocket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
this.parsePacket(packet.getData(), packet.getAddress(), packet.getPort());
}
}
private void parsePacket(byte[] data, InetAddress address, int port) {
String dataString = new String(data).trim();
PacketType type = Packet.lookupPacket(dataString.substring(0, 2));
Packet packet = null;
switch (type) {
default:
break;
case CONNECT:
System.out.println("Here");
this.sendByteData("-3".getBytes(), address, port);
break;
case INVALID:
break;
case LOGIN:
packet = new PacketLogin(data);
System.out.println("[" + address.getHostAddress() + ":" + port + "] " + ((PacketLogin)packet).getUsername() + " - Has just joined the server!");
PlayerMP playerLogin = new PlayerMP(game, ((PacketLogin)packet).getUsername(), address, port);
this.addConnection(playerLogin, (PacketLogin)packet);
break;
case DISCONNECT:
packet = new PacketDisconnect(data);
System.out.println("[" + address.getHostAddress() + ":" + port + "] " + ((PacketDisconnect)packet).getUsername() + " - Has just left the server!");
this.removeConnection((PacketDisconnect)packet);
break;
case MOVEMENT:
System.out.println("Here");
packet = new PacketMovement(data);
this.players.get(this.getPlayerIndex(((PacketMovement)packet).getUsername())).setX(((PacketMovement)packet).getX());
this.sendByteDataToAll(packet.getData(), address, port);
break;
}
}
public void addConnection(PlayerMP player, PacketLogin login) {
boolean alreadyOn = false;
for(PlayerMP p : players) {
if(player.getUsername().equals(p.getUsername())) {
if(p.IPaddress == null) {
p.IPaddress = player.IPaddress;
}
if(p.port == -1) {
p.port = player.port;
}
alreadyOn = true;
} else if(!player.getUsername().equals(p.getUsername())) {
this.sendByteDataToAll(login.getData(), player.IPaddress, player.port);
login = new PacketLogin(p.getUsername());
this.sendByteData(login.getData(), player.IPaddress, player.port);
} else {
System.out.println("Error whilst trying to send data to clients");
this.sendByteData(login.getData(), p.IPaddress, p.port);
}
}
if(!alreadyOn) {
this.players.add(player);
}
}
public void removeConnection(PacketDisconnect packet) {
this.players.remove(this.getPlayerIndex(packet.getUsername()));
packet.writeData(this);
}
public PlayerMP getPlayer(String username) {
for(PlayerMP p : players) {
if (p.getUsername().equals(username)) {
return p;
}
}
return null;
}
public int getPlayerIndex(String username) {
int index = 0;
for(PlayerMP p : players) {
if (p.getUsername().equals(username)) {
break;
}
index++;
}
return index;
}
public void sendByteData(byte[] data, InetAddress IPaddress, int port) {
if(port != -1) {
DatagramPacket out = new DatagramPacket(data, data.length, IPaddress, port);
try {
this.dataSocket.send(out);
System.out.println("Sending byte[] data to ClientHandler(" + out.getAddress().getHostAddress() + ":" + out.getPort() + ")");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void sendByteDataToAll(byte[] data) {
for(PlayerMP p : players) {
sendByteData(data, p.IPaddress, p.port);
}
}
public void sendByteDataToAll(byte[] data, InetAddress IPaddress, int port) {
for(PlayerMP p : players) {
if(p.IPaddress != IPaddress) {
sendByteData(data, p.IPaddress, p.port);
} else if(p.port != port) {
sendByteData(data, p.IPaddress, p.port);
} else {
}
}
}
public void close() {
this.sendByteDataToAll("-2".getBytes()); //Disconnects all players when server is closed
this.players.clear();
}
}
DisplayHandler.java(创建客户端和服务器处理程序的位置)
@Override
public void start() {
this.shread.start();
this.soundThread.start();
if(JOptionPane.showConfirmDialog(this, "Do you want to host a lan server?") == 0) {
this.server = new ServerHandler(this, 2048); //Creates server if user wants to. Prams: DisplayHandler, int port - the port the server should host on
this.server.start();
System.out.println("Done1");
}
this.client = new ClientHandler(this, "MYEXTERNALIP", 2048); //Creates Client. Prams: DisplayHandler, String IP - The servers IP, int port - Servers port
this.client.start();
this.setCurrentDisplay(dispMMenu);
this.onOpen();
this.client.callHost();
System.out.println("Done");
//this.sound.addMidi("finalcountdown", "test.mid");
//this.sound.playMid("finalcountdown", true);
}