我知道标题很糟糕,但让我解释一下我的情况。好的,我正在制作一个服务器,它坐在一边并与我的 Minecraft 客户端进行通信。我可以让一个客户端连接和传输数据,第四个。当我尝试与第二个客户端连接时,出现错误:
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
at java.io.ObjectOutputStream.<init>(Unknown Source)
at ConnectionHandler.setupStreams(ConnectionHandler.java:71)
at ConnectionHandler.HandleChat(ConnectionHandler.java:30)
at ConnectionHandler.<init>(ConnectionHandler.java:23)
at Server.waitForConnection(Server.java:118)
at Server.RunAll(Server.java:65)
at Server.run(Server.java:50)
at ServerTest.main(ServerTest.java:9)
因此,结果代码如下:
setupStreams:第 71 行
public static void setupStreams() throws IOException
{
for(int i = 1; i <= Server.ConnectionArray.size(); i++)
{
Socket TempSocket = (Socket) Server.ConnectionArray.get(i - 1);
output = new ObjectOutputStream(TempSocket.getOutputStream());//Line 71
output.flush();
input = new ObjectInputStream(TempSocket.getInputStream());
whileChatting();
}
}
现在我觉得最好解释一下所有这些代码是如何设置的:
它从一个名为 ServerTest.Java 的类开始:
public class ServerTest
{
public static void main(String[] args)
{
Server Minecraft = new Server();
Minecraft.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Minecraft.run();
}
}
我称这个对象为“我的世界”。
现在它引用的类也实现了 Runnable 类并以 run() 方法开始。这是那个方法:
@Override
public void run()
{
RunAll();
}
public void RunAll()
{
ConnectionHandler.showMessage("Waiting for client connections...");
try
{
server = new ServerSocket(1337, 10);
while(true)
{
try
{
waitForConnection();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
catch(IOException Exception)
{
Exception.printStackTrace();
}
finally
{
ConnectionHandler.closeCrap();
}
}
现在从这里开始等待连接,我认为它会反复循环,但我不知道。这是该方法的代码:
public void waitForConnection() throws IOException
{
connection = server.accept();
ConnectionArray.add(connection);
ConnectionHandler connections = new ConnectionHandler(connection);
connection = null;
}
现在我认为这个方法的作用是接受来自客户端的传入连接,然后将该连接添加到我的套接字数组中,然后将套接字交给处理程序类,然后将原始套接字设置回 Null 以等待另一个传入连接.
现在这将我们带到 ConnectionHandler 类。在这里,它需要一个套接字 X 并将其设置为全局套接字,如下所示:
static Socket Socket;
public PrintWriter Out;
String Message = "";
public static ObjectOutputStream output;
public static ObjectInputStream input;
public static int Players = 0;
public ConnectionHandler(Socket X)
{
this.Socket = X;
HandleChat();
}
该类还实现了 Runnable 类。但正如您所看到的,它将全局套接字设置为 X 然后运行 HandleChat(); 这是方法:
public static void HandleChat()
{
try
{
setupStreams();
}
catch (IOException e)
{
e.printStackTrace();
}
}
如您所见,这一切都在运行 setupStreams(); 方法。这也是该方法:
public static void setupStreams() throws IOException
{
for(int i = 1; i <= Server.ConnectionArray.size(); i++)
{
Socket TempSocket = (Socket) Server.ConnectionArray.get(i - 1);
output = new ObjectOutputStream(TempSocket.getOutputStream());
output.flush();
input = new ObjectInputStream(TempSocket.getInputStream());
whileChatting();
}
}
现在我“思考”这个方法创建一个名为 TempSocket 的新套接字,并使其 = 数组中的最新连接,然后将输出和输入流设置到该套接字,从而为该单个客户端生成一个套接字,然后运行 whileChatting(); 这是生成的代码:
public static void whileChatting() throws IOException
{
String message = "";
do
{
try
{
message = (String) input.readObject();
showMessage("\n" + message);
sendMessage("", message);
}
catch(ClassNotFoundException classNotFoundException)
{
ConnectionHandler.showMessage("\n idk wtf that user sent!");
}
}while(!message.equals("/stop"));
}
再次与“思考”在这里。我认为读取对象被设置为字符串消息;然后被发送到客户端并显示在控制台屏幕上。(Swing) 下面是方法 (Send) 和 (Show) 的代码:
public static void sendMessage(String message, String returnedMessage)
{
try
{
if(!message.isEmpty())
{
output.writeObject("\247c[Server]\247d " + message);
}
else
{
output.writeObject(returnedMessage);
}
output.flush();
showMessage("\n[Server] " + message);
}
catch(IOException ioException)
{
Server.chatWindow.append("\n ERROR: DUDE I CANT SEND THAT MESSAGE");
}
}
static void showMessage(final String text)
{
SwingUtilities.invokeLater
(
new Runnable()
{
public void run()
{
Server.chatWindow.append(text);
}
}
);
}
现在你可以在这里看到,当我想在客户端显示一条消息时;我希望它看起来像:[Server] 文本。此外,您会注意到它还 sys 返回了消息。我将客户端设置为仅发送到服务器,然后在屏幕上显示返回的内容,所以可以说我输入“Hay”它在发送时不会在我的屏幕上显示任何内容,但是一旦服务器收到它,它会将确切的文本发送回给我每个人。这就是 sendMessage(); 方法。现在的显示方法比较简单。它在接收时显示文本。
简而言之,这就是代码。我宁愿给你留下太多的信息,也不愿让你坐在这里想知道发生了什么。我将再一次更深入地解释我的情况。我正在制作一个与我的 Minecraft 客户端通信的服务器。一个客户端连接正常,但是当另一个客户端尝试连接它时出错并且当第一个客户端断开连接时,服务器将不允许客户端重新连接。我认为这可能与连接数组有关,并且套接字在断开连接时没有从数组中删除,但我不知道。现在最后,我的问题是如何解决这些错误?提前感谢我对这个问题的任何回复。