2012-11-10 118 views
0

我對套接字很陌生,希望有人能幫助我。我有一些工作,但它不是很快發送信息,所以我已經重構,現在無法回到任何有效的工作。這個問題似乎是,只有發佈的第一條消息被讀取,然後接收器坐在client = listener.accept();即使我很確定發件人仍在發送消息Socket問題 - 只讀第一條消息

任何人都可以看到我可能會做錯在這裏,請嗎?

由於

public class Sender { 
     Socket server = null; 
     DataInputStream inp = null; 
     PrintStream outp = null; 

     public Sender(){ 
      server = new Socket("127.0.0.1" , 3456); 
      outp = new PrintStream(server.getOutputStream()); 
     } 

     private void connectAndSendToServer(String message) { 
      outp = new PrintStream(server.getOutputStream()); 
      outp.print(message + "\n"); 
      outp.flush(); 

     } 
    } 

Receiver類

public class Receive{ 


    public String receiveMessage(int port) { 
     String message= null; 
     ServerSocket listener = null; 
     Socket client = null; 
     try{ 
      listener = new ServerSocket(port); 
      client = listener.accept();   
      BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); 
      return br.readLine(); 

     } 
     ... 
     finally{ 
      try { 
       if(client!=null && listener!=null){ 
        client.close(); 
        listener.close(); 
       } 
      } 
      catch (IOException e) { 

      } 
     } 
     return message; 
    } 
} 
+1

事實上,您實例化PrintStream兩次可能是問題的一部分。 – Flawyte

回答

2

這是因爲一個ServerSocket被用作入口點正常的插槽。 accept()是一種阻塞操作,通常在接收/發送數據到正常Socket的線程上進行。它坐在那裏,等待一個新的連接產生一個新的Socket然後用於數據。

這意味着,在接收消息時,您應該調用readLine()以從特定套接字讀取數據。在receiveMessage中有accept是錯誤的,因爲它是一個不同的操作,甚至是阻塞。

Socket socket = serverSocket.accept(); 

ClientThread thread = new ClientThread(socket); 

class ClientThread extends Thread { 
    Socket socket; 

    public void run() { 
    while (!closed) { 
     String line = reader.readLine(); 
     ... 
    } 
    } 

你並不需要有每一個客戶一個線程,雖然,但你至少需要兩個肯定的,如果你想使你的服務器接受連接數大於1

+0

這工作,謝謝你 – Biscuit128

2

你更大的沒有正確使用ServerSocket。你不應該爲每個消息創建一個新的實例,而是將它用作數據成員,並且運行一個無限循環來獲得一個新的客戶套接字連接。因爲您在本地創建它,所以套接字將被關閉,因爲當您從方法返回時,該對象不再使用並被引用(並因此被GC'ed)。
喜歡的東西(<條件滿足>是僞代碼定義你的條件,接受新的連接):

while(< condition met >) { 
    try { 
     client = listener.accept(); 
     BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); 
     String str = br.readLine(); 
     //do something with str 
    } finally { 
     //close client socket 
    }  
} 

更好的方法將是處理客戶端套接字在不同的線程,以便主線程是回納而您可以並行處理客戶端套接字。

+0

你應該改變爲布爾或真正的代碼中斷。 – Err

+0

完成了,謝謝Err – breezee

0

-試試這個我寫的基本聊天服務器。該服務器只是保持循環運行,並將客戶端發送的消息廣播到與此服務器關聯的所有其他客戶端。

-我希望這段代碼對您有所幫助。

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.ArrayList; 

public class Server { 

    // ///----------------------------------------Instance Variable Fields 
    ServerSocket ss = null; 
    Socket incoming = null; 

    // ///----------------------------------------Instance Variable Fields 

    // ///---------------------------------------- static Variable Fields 
    public static ArrayList<Socket> socList = new ArrayList<Socket>(); 

    // ///---------------------------------------- static Variable Fields 

    public void go() { 

     try { 

      ss = new ServerSocket(25005); 

      while (true) { 

       incoming = ss.accept(); 
       socList.add(incoming); 
       System.out.println("Incoming: " + incoming); 
       new Thread(new ClientHandleKaro(incoming)).start(); 

      } 

     } catch (IOException e) { 

      e.printStackTrace(); 
     } finally { 

      try { 
       ss.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

    } 

    class ClientHandleKaro implements Runnable { 

     InputStream is = null; 
     OutputStream os = null; 
     InputStreamReader isr = null; 
     BufferedReader br = null; 
     PrintWriter pw = null; 
     boolean isDone = false; 

     Socket sInThread = null; 

     public ClientHandleKaro(Socket sxxx) { 

      this.sInThread = sxxx; 

     } 

     @Override 
     public void run() { 

      if (sInThread.isConnected()) { 

       System.out.println("Welcamu Clienta"); 
       System.out.println(socList); 
      } 

      try { 
       is = sInThread.getInputStream(); 
       System.out.println("IS: " + is); 
       isr = new InputStreamReader(is); 
       br = new BufferedReader(isr); 

       os = sInThread.getOutputStream(); 
       pw = new PrintWriter(os, true); 

       String s = new String(); 

       while ((!isDone) && (s = br.readLine()) != null) { 

        String[] asx = s.split("-"); 
        System.out.println("On Console: " + s); 

        // pw.println(s); 

        Thread tx = new Thread(new ReplyKaroToClient(s, 
          this.sInThread)); 
        tx.start(); 

        if (asx[1].trim().equalsIgnoreCase("BYE")) { 

         System.out.println("I am inside Bye"); 
         isDone = true; 

        } 
       } 
      } catch (IOException e) { 

       System.out.println("Thanks for Chatting....."); 
      } finally { 

       try { 
        Thread tiku = new Thread(new ByeByeKarDo(sInThread)); 
        tiku.start(); 
        try { 
         tiku.join(); 
        } catch (InterruptedException e) { 

         e.printStackTrace(); 
        } 

        System.out.println("Accha to hum Chalte hain !!!"); 
        System.out.println(socList); 

        br.close(); 
        pw.close(); 
        sInThread.close(); 

       } catch (IOException e) { 

       } 
      } 

     } 

    } 

    class ReplyKaroToClient implements Runnable { 

     public String mString; 
     public Socket mSocket; 

     public ReplyKaroToClient(String s, Socket sIn) { 

      this.mString = s; 
      this.mSocket = sIn; 
     } 

     @Override 
     public void run() { 

      for (Socket sRaW : socList) { 

       if (mSocket.equals(sRaW)) { 
        System.out.println("Mai same hun"); 
        continue; 

       } else { 
        try { 
         new PrintWriter(sRaW.getOutputStream(), true) 
           .println(mString); 
        } catch (IOException e) { 

         System.out.println("Its in Catch"); 

        } 
       } 
      } 

     } 

    } 

    class ByeByeKarDo implements Runnable { 

     Socket inCom; 

     public ByeByeKarDo(Socket si) { 

      this.inCom = si; 
     } 

     @Override 
     public void run() { 

      try { 
       new PrintWriter(inCom.getOutputStream(), true) 
         .println("You have Logged Out of Server... Thanks for ur Visit"); 
      } catch (IOException e) { 

       e.printStackTrace(); 
      } 

     } 

    } 

    public static void main(String[] args) { 

     new Server().go(); 
    } 
}