如何正确关闭套接字然后重新打开它?

问题描述:

我正在为一个我正在开发的课程开发一款游戏,并且大约有99%完成了。但是,我意识到存在一个问题:如果服务器和客户端断开连接,并且客户端尝试重新连接(并且服务器备份并运行正常),则客户端不会建立新连接。如何正确关闭套接字然后重新打开它?

服务器和客户端都是多线程的。如果我向客户端发送一个Kick消息,那么客户端将关闭其套接字。如果我重新连接,即使每次按下连接时都会关闭套接字:SocketException:构建一个新的Client,它基本上只是一个创建套接字并通过get/send线程连接到服务器的类。

你认为我有什么不合逻辑的吗?这就像它试图使用构造的旧套接字和客户端,但如果我做了一些println调用,我可以看到它构建了一个新的,并且它们位于不同的内存位置。

谢谢!

+0

检查这个问题 - > http://*.com/questions/2456607/can-i-close-and-重新打开插座 –

+1

这似乎没有帮助。我意识到新客户端正在连接,因为如果我使用其他名称进行连接,则新名称将在发送数据时实现。我忘了提及,无论出于何种原因,数据收到罚款。每当我尝试写入输出流时,我都会遇到socketclosed异常。 – user1089097

关闭套接字后,无法重新使用它来在服务器和客户端类之间共享其他数据。从Java Socket API,在close()方法描述:

当前在此插座阻止在I/O操作的任何线程将 引发SocketException。

一旦套接字已关闭,它不可用于网络使用的进一步 (即不能重新连接或反弹)。需要创建一个新的套接字 。

关闭此套接字还将关闭套接字的InputStream和OutputStream。

如果此套接字有关联的频道,那么该频道也会关闭 。

然后,无法关闭套接字并重新打开它。我想这就是抛出异常的原因。

+0

感谢您的输入。我正在构建一个新的Socket,最奇怪的是,在我构建新的Socket之后,如果在连接后立即向输出流写入某些内容,它会将其写入并正确接收响应。但是如果我稍后调用writeObject,它会给出错误! – user1089097

+0

@ user1089097对不起,我看到您的评论后添加了我的问题。这真是一个奇怪的问题。也许你在输出流中写入之前关闭了服务器套接字。你可以在你的问题中发布一些代码吗? –

+0

我已经找出了问题所在。聊天室发送给错误的客户端 - 客户端或服务器没有任何问题。我不知道如何解决这个问题,因为我用客户端构建了视图......但至少我知道为什么。谢谢。 – user1089097

它可以很容易!我做了这个程序(服务器端):

import java.net.ServerSocket; 
import java.net.Socket; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 

public class Host{ 
    public static void main(String[] args) throws Exception{ 
     while(true){ 
      ServerSocket ss = new ServerSocket(1300); 
      Socket s = ss.accept(); 
      DataInputStream din = new DataInputStream(s.getInputStream()); 
      String msgin = din.readUTF(); 
      System.out.println(msgin); 
      ss.close(); 
      s.close(); 
      din.close(); 
     } 
    } 
} 

客户端:

import java.net.Socket; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 

public class Client{ 
    public static void main(String[] args) throws Exception{ 
     while(true){ 
      Socket s = new Socket("localhost", 1300); 
      DataOutputStream dout = new DataOutputStream(s.getOutputStream()); 
      dout.writeUTF("hello"); 
      s.close(); 
      dout.close(); 
     } 
    } 
} 

它的工作原理,怎么一回事,因为你可以用相同的ServerSocket声明万吨插座,因此,例如这个工程太:

ServerSocket ss = new ServerSocket(1300); 
Socket a = ss.accept(); 
Socket b = ss.accept(); 
Socket c = ss.accept(); 

并且你有3个套接字...... 记住:当你声明一个套接字时,java等待客户端连接! 代码:

客户:

import java.net.Socket; 

public class client { 
    public static void main(String[] args) throws Exception{ 
     Socket a = new Socket("localhost", 1300); 
     Thread.sleep(3000); 
     Socket b = new Socket("localhost", 1300); 
     Thread.sleep(3000); 
     Socket c = new Socket("localhost", 1300); 
     Thread.sleep(3000); 
     a.close(); 
     b.close(); 
     c.close(); 
    } 
} 

服务器:

import java.net.ServerSocket; 
import java.net.Socket; 

public class server { 
    public static void main(String[] args) throws Exception{ 
     ServerSocket ss = new ServerSocket(1300); 
     System.err.println("Listening..."); 
     Socket a = ss.accept(); 
     System.err.println("1"); 
     Socket b = ss.accept(); 
     System.err.println("2"); 
     Socket c = ss.accept(); 
     System.err.println("3"); 
    } 
}