首页 文章

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

提问于
浏览
5

我正在开发一个我正在上课的游戏,它完成了大约99% . 但是,我意识到存在一个问题:如果服务器和客户端断开连接,并且客户端尝试重新连接(并且服务器已备份且运行正常),则客户端不会 Build 新连接 .

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

你觉得我有什么不合逻辑吗?它就像它试图使用构造的旧Socket和Client,但是如果我做了一些 println 调用,我可以看到它确实构造了一个新的并且它们位于不同的内存位置 .

谢谢!

2 回答

  • 2

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

    此套接字上的I / O操作中当前阻塞的任何线程都将抛出SocketException . 一旦套接字关闭,它就不能用于进一步的网络使用(即不能重新连接或反弹) . 需要创建一个新的套接字 . 关闭此套接字也将关闭套接字的InputStream和OutputStream . 如果此套接字具有关联的通道,则通道也将关闭 .

    然后, it isn't possible to close a socket and reopen it . 我认为,这就是抛出异常的原因 .

  • 8

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

    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个套接字......请记住:当你声明一个Socket时,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");
        }
    }
    

相关问题