【问题标题】:Trying to figure out best way to close socket connection when my very simple chat server quits当我非常简单的聊天服务器退出时,试图找出关闭套接字连接的最佳方法
【发布时间】:2011-12-08 11:34:51
【问题描述】:

我正在尝试制作一个简单的聊天服务器。我有一个 siisue,程序将在一个线程上运行,结束一个无限循环,接受端口 80 上的套接字连接。现在如果我重新运行程序,它会给我一个地址错误,即端口 80 没有被释放。
现在服务器运行在一个单独的线程上,主线程只是等待某人通过使用 system.in.read 按下回车键。似乎在java中,当程序退出时,它不会自动关闭所有连接。 我正在考虑让主线程发送一条服务器线程会读取的消息。它会告诉服务器线程关闭。 有没有更好的方法来做到这一点?

代码 公共类 cServerThread 实现 Runnable {

Thread runner;
public cServerThread() {
}

public cServerThread(String threadName) {
    runner = new Thread(this, threadName); // (1) Create a new thread.
    System.out.println(runner.getName());
    runner.start(); // (2) Start the thread.
}

public void run() {
    //Display info about this particular thread
    System.out.println(Thread.currentThread());
     cServer mServer = new cServer();
      mServer.run();

}

}

公共类 cServer {

boolean StopFlag;
 String header;
Socket connection;
ServerSocket  server;
StringBuffer request;
OutputStream out;



 public boolean ReadSize(InputStream in)
 {
    // read in one line
     try{
         request = new StringBuffer(1000);
        boolean f=true;
        int s=43;
        while( s-->0 )
        {
            int c=in.read();
            char a=(char)c;
            request.append(a);
                } // end while

     } catch(IOException ec)
        {
            System.out.println(ec.getMessage());    
        }

     System.out.println("last line");
        System.out.println(request);
        int p=request.lastIndexOf("stop");
        if (p!=-1)
            StopFlag=true;

    return true; 
 }


 public boolean ReadLine(InputStream in)
 {
    // read in one line
     try{
         request = new StringBuffer(1000);
        boolean f=true;
        while(true)
        {
            int c=in.read();
            if (c=='\r') 
                {
                // next should be a \n
                 c=in.read();
                if (f==true)
                    return false;
                 break;
                }
            f=false;
            request.append((char)c);
                } // end while

     } catch(IOException ec)
        {
            System.out.println(ec.getMessage());    
        }

        System.out.println(request);
        int p=request.lastIndexOf("stop");
        if (p!=-1)
            StopFlag=true;

    return true; 
 }


 public void ReadHeader()
 {
    // read in one line
     try{
        request = new StringBuffer(1000);
        System.out.println("get connection reading in data \r");
        InputStream in = new BufferedInputStream( connection.getInputStream() );
        StopFlag=false;
        for(int i=0;i<11;i++)
            ReadLine(in);
        ReadSize(in);


     } catch(IOException ec)
        {
            System.out.println(ec.getMessage());    
        }

 }

 public void SendReply()
 {
        // set up header
     String content="test html ted\r\n cat2";

      String header="HTTP/1.0 200 Ok\r\n"+
      "Server: OneFile 1.0\r\n"+
      "Content-length: "+content.length() +"\r\n"+
      "Content=type: "+"text/html " +"\r\n\r\n";
    //  header=header.getBytes("ASCII");
      byte[] bHeader;

      try{
      bHeader=header.getBytes("ASCII");

        out.write( header.getBytes("ASCII") );
        out.write(content.getBytes("ASCII"));
        out.flush();



      } catch(IOException ec)
        {
          System.out.println(ec.getMessage());
        }

 }

 public int GetPort()
 {
  return 90;     
 }


 public void run()
  {
     String content="test html ted2 \r\n fred";

    // set up header
      header="HTTP/1.0 200 Ok\r\n"+
      "Server: OneFile 1.0\r\n"+
      "Content-length: "+content.length() +"\r\n"+
      "Content=type: "+"text/html " +"\r\n\r\n";
    //  header=header.getBytes("ASCII");


      try{
        connection = null;
        server = new ServerSocket(87); // port 62

        // Loop forever
        while(true)
        {
            ///////////////////////////////////////////////////
            // get a new connection
            ///////////////////////////////////////////////////
            System.out.println("Aceepting connections on port 86 \r");

            try{
                // Get New Connection
                connection=server.accept();

                // Create a buffer stream to connection
                out=new BufferedOutputStream( connection.getOutputStream() ); 

                // Read in the header
                ReadHeader();

                // Read in the message id
                // Send the reply back
                SendReply();

                if (StopFlag)
                {
                    System.out.println("shutting down \r");
                    connection.close();
                    break;
                }
                /*
                byte[] bHeader;
                bHeader=header.getBytes("ASCII");

                out.write( header.getBytes("ASCII") );
                out.write(content.getBytes("ASCII"));
                out.flush();

                int p=request.lastIndexOf("stop");
                if (p!=-1)
                {
                    System.out.println("shutting down \r");
                    connection.close();
                    break;
                }
                */
            } catch(IOException ec)
            {
                System.out.println(ec.getMessage());    
            }
            finally{
                if (connection != null )
                    connection.close();
            }

            } // end while

    } catch(IOException ec)
    {
        System.out.println(ec.getMessage());            
    }

  } // end run


} // end class

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    ServerSocket.setReuseAddress(true)。出于技术原因,不是 Java,而是操作系统,特别是 TCP/IP 堆栈,使端口保持打开状态,在 TIME_WAIT 状态下保持两分钟。

    【讨论】:

    • 我在哪里可以找到这些“技术原因”的解释?
    • @Jay 在 RFC 中。收到关闭的对等方必须让端口在 2 个 MSL 中不使用,以便区分此连接上的剩余流量与新连接上的剩余流量。
    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2019-05-24
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    相关资源
    最近更新 更多