我最近開始製作2D java遊戲,並在2天前開始製作一個tcp服務器,現在我所有的其他問題都已修復,我想解決這個事實,即客戶端可以只有連接到服務器,當它在同一設備上,並使用設備的靜態IP,雖然它不能連接使用我的WAN IP地址,我有端口轉發,我檢查了很多端口檢查器網站,他們都可以看到我的服務器,我的防火牆也被禁用,但客戶端無法看到使用wan ip的服務器,我在同一個端口上創建了一個minecraft服務器(我的世界服務器也是tcp),其他人可以使用我的wan ip連接。當客戶端嘗試使用我的wan ip進行連接時,它會發出Connection Refused異常。我究竟做錯了什麼?Java TCP客戶端 - 服務器NAT連接拒絕
客戶端(無法連接到服務器通過NAT):
package com.diedericksclan.main.network;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import com.diedericksclan.main.network.handling.PlayerMP;
public class ServerThread extends Thread {
private ServerHandler server;
private ServerSocket dataSocket;
private Socket socket;
private InetSocketAddress address;
private int megabyte = 1024 * 1024;
private int dedicated = 1024;
public int RAM = megabyte * dedicated;
private ArrayList<Client> clients = new ArrayList<Client>();
public ServerThread(ServerHandler server, String serverIP, int ram, int backlog) throws Exception {
super(serverIP);
this.server = server;
this.dedicated = ram;
String ip = "localhost";
int port = 2048;
if(serverIP.contains(":")) {
ip = serverIP.split(":")[0];
port = Integer.parseInt(serverIP.split(":")[1]);
} else {
ip = serverIP;
port = 2048;
}
this.dataSocket = new ServerSocket();
this.dataSocket.setReuseAddress(true);
this.address = new InetSocketAddress(InetAddress.getByName(ip), port);
this.dataSocket.bind(address, 0);
}
public ServerThread(ServerHandler server, String ip) throws Exception {
this(server, ip, 1024, 0);
}
public void run() {
while(true) {
try {
socket = dataSocket.accept();
socket.setKeepAlive(true);
socket.setSendBufferSize(megabyte);
socket.setSendBufferSize(megabyte);
socket.setTcpNoDelay(true);
socket.setReuseAddress(true);
InetSocketAddress clientAddress = new InetSocketAddress(socket.getInetAddress(), socket.getPort());
System.out.println("Starting");
if(getClients().size() > 0) {
for(Client c : getClients()) {
if(clientAddress != c.socket.getLocalSocketAddress()) {
Client client = new Client(socket, clientAddress);
getClients().add(client);
client.start();
System.out.println("Added new client!");
break;
}
}
} else {
Client client = new Client(socket, clientAddress);
getClients().add(client);
client.start();
System.out.println("Added new client!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public synchronized void sendData(byte[] data, InetAddress IPaddress, int port) {
if(this.getClient(new InetSocketAddress(IPaddress, port)) != null) {
this.getClient(new InetSocketAddress(IPaddress, port)).sendData(data);
}
}
public void serverShutdown() {
try {
this.dataSocket.close();
if(this.socket != null) this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public int getClientIndex(InetSocketAddress address) {
int index = 0;
for(Client c : getClients()) {
if(c.socket.getRemoteSocketAddress().equals(address)) {
break;
}
index++;
}
System.out.println("Getting client index...");
return index;
}
public synchronized ArrayList<Client> getClients() {
return this.clients;
}
private Client getClient(InetSocketAddress address) {
for(Client c : getClients()) {
if(c.socket.getRemoteSocketAddress().equals(address)) {
return c;
}
}
return null;
}
public class Client extends Thread {
DataInputStream in;
DataOutputStream out;
Socket socket;
public Client(Socket sock, InetSocketAddress IPaddress) {
try {
socket = sock;
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while(true) {
try {
byte[] data = new byte[in.readInt() - 4];
in.read(data);
server.parsePacket(data, socket.getInetAddress(), socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void sendData(byte[] data) {
try {
out.writeInt(data.length + 4);
out.write(data);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我真的很感激,如果有人可以幫助:
package com.diedericksclan.main.network;
import java.io.*;
import java.net.*;
import java.util.Enumeration;
public class ClientThread extends Thread {
private ClientHandler client;
private Socket socket;
private InetSocketAddress address;
private int megabyte = 1024 * 1024;
private DataInputStream in;
private DataOutputStream out;
public ClientThread(ClientHandler client, InetSocketAddress address) {
this.client = client;
this.address = address;
socket = new Socket();
try {
socket.setSendBufferSize(megabyte);
socket.setSendBufferSize(megabyte);
socket.setTcpNoDelay(true);
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(this.getIP(), 0));
System.out.println(socket.getLocalAddress().getHostAddress() + ":" + socket.getLocalPort() + " is a new client!");
socket.connect(address);
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private InetAddress getIP() throws SocketException {
Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
NetworkInterface ni;
while (nis.hasMoreElements()) {
ni = nis.nextElement();
if (!ni.isLoopback() && ni.isUp()) {
for (InterfaceAddress ia : ni.getInterfaceAddresses()) {
if (ia.getAddress().getAddress().length == 4) {
return ia.getAddress();
}
}
}
}
return null;
}
long starttime;
long endtime;
long overall;
public void run() {
byte[] data;
while(true) {
try {
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
data = new byte[in.readInt() - 4];
in.read(data);
client.parsePacket(data, socket.getInetAddress(), socket.getPort());
endtime = System.nanoTime();
overall = endtime - starttime;
//System.out.println("CLIENT >> SERVER >> CLIENT - Time was: " + overall + " nano seconds!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public synchronized void sendData(byte[] data) {
try {
try { socket.connect(address); } catch (IOException e) {}
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
starttime = System.nanoTime();
out.writeInt(data.length + 4);
out.write(data);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void serverShutdown() {
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服務器(可以通過一切,但客戶可以看到) 。 -Regards 用戶.....
我讓我的朋友從他們的電腦上測試它,但它沒有工作 – marko5049
「它沒有工作」是什麼意思?「TCP連接是否完成?他們是否收到錯誤消息? –
客戶端拋出一個連接在嘗試通過我的公共wan ip進行連接時拒絕異常 – marko5049