簡體   English   中英

即使建立連接后,serversocket.accept()方法也會阻塞

[英]serversocket.accept() method blocks even after connection is established

服務器

    public class Server {

class ServerHelper implements Runnable
    {
        InputStream is;
        private InputStreamReader isr;
        private BufferedReader br;

        public ServerHelper(InputStream is) {
            this.is  = is;
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);
        }



         private void display() throws IOException {

            String s = "";
            System.out.print("client says : ");
            while ( ( s = br.readLine() ) != null ) {                
                System.out.print(s + " ");
            }
        }

        @Override
        public void run() {
            try {
                display( );
            } catch (IOException ex) {
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        void start( ) throws Exception{
          ServerSocket ss = new ServerSocket(5555);

             while (true) {            
                System.out.println("waiting for conn..");
              Socket accept =   ss.accept();//code hangs over here and doesn't proceed ahead

                 if( accept == null )
                     System.out.println("got null...");
                 System.out.println("got the client req...");
                 ServerHelper sh = new ServerHelper(accept.getInputStream());
                 Thread t = new Thread(sh);
                 t.start();
             }

        }

         public static void main(String[] args) {
             try {
                // TODO code application logic here
                new Server().start();
             } catch (Exception ex) {
                 Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            }
         }

客戶

public class Client {

void start( ) throws Exception{
    System.out.println("enter window size ");
    Scanner sc = new Scanner(System.in);
    int wsize = sc.nextInt();
    Socket s = new Socket("127.0.0.1", 5555);
    System.out.println("is connected .." + s.isConnected());

    OutputStream outputStream = s.getOutputStream();
    PrintWriter pw = new PrintWriter(outputStream);
    String c  = "y";
    int j = 0;
    do{
        String se = "";
        for (int i = 0; i < wsize; i++) {
            j++;
            se = se + String.valueOf(j);

        }
        pw.println(se);
        pw.flush();

        System.out.println("do u wanna send more....?(y|n)");
        c =  sc.next();
    }while( c.equalsIgnoreCase("y") );

}
public static void main(String[] args) {
    try {
        // TODO code application logic here
        new Client().start();
    } catch (Exception ex) {
        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
    }
}

}

Socket accept =   ss.accept();

在這里我的代碼掛斷了,我知道它阻止了io,但是在客戶端,我確實驗證了客戶端是否已連接,但是它顯示了連接... accept()有什么問題? 我為所有TCP應用程序都以類似的方式編碼,但這很奇怪..能幫上什么忙嗎

我還為那些想要看一下該類的人添加了ServerHelper代碼。

看一下您的代碼:

while (true) {            
      System.out.println("waiting for conn..");
      Socket accept =   ss.accept();
      .................
}

您將ss.accept()稱為無限循環。 客戶端連接后, accept()返回Socket實例。 然后,將此套接字傳遞給在其自己的線程中運行的服務器幫助程序,並返回到ss.accept() ,以便您的服務器准備接受其他客戶端。 您的代碼看起來不錯。 不幸的是,您還沒有發送ServerHelper代碼,也沒有解釋您的客戶端是否成功向服務器發送了數據,但是到目前為止一切都還不錯。

如果對accept的調用確實處於阻塞狀態,則您正在運行另一個正在5555上偵聽並綁定到“ 127.0.0.1”的程序。 您的客戶端正在連接到該其他程序,因此ss.accept仍會阻止。

解決的辦法是找到並殺死其他進程

附加信息:

由於未在服務器套接字中指定綁定地址,因此將其綁定到“ 0.0.0.0”(所有接口)。

一個進程可以綁定到127.0.01,另一個可以綁定到0.0.0.0(至少在Windows上)。 我從tcpview復制了一些數據。 第二列是進程ID。

java.exe    5944    TCP 0.0.0.0 5555    0.0.0.0 0   LISTENING                                       
java.exe    5944    TCPV6   [0:0:0:0:0:0:0:0]   5555    [0:0:0:0:0:0:0:0]   0   LISTENING                                       
java.exe    5608    TCP 127.0.0.1   5555    0.0.0.0 0   LISTENING       

我可以使用telnet 10.101.16.28 5555 (我的本地IP地址)連接到進程5944或使用telnet 127.0.0.1 5555連接到進程5608

當然會阻塞。 它正在等待連接。 那就是應該做的。 BTW檢查accept()的結果是否為null是毫無意義的。 它不會為空。 可能這是您的誤解:如果沒有傳入的連接,您是否期望它返回null? 它不會那樣做。 請參閱Javadoc。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM