2014-02-18 107 views
1

目前我正在使用java發送數據的服務器/客戶端應用程序Runnable線程。問題是客戶端正在發送數據,當服務器開始讀取數據時,客戶端已經完成並關閉了服務器端只有部分數據到達的連接,它們是否可以設置爲同步?與客戶端Java套接字同步服務器

這是客戶

private void ConnectionToServer(final String ipAddress, final int Port) { 
    final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10); 

    Runnable serverTask = new Runnable() { 
     @Override 
     public void run() { 
      try { 
       socket = new Socket(ipAddress, Port); 

       bos = new BufferedOutputStream(socket.getOutputStream()); 
       dos = new DataOutputStream(socket.getOutputStream()); 

       File f = new File("C:/Users/lukeLaptop/Downloads/RemoveWAT22.zip"); 

       String data = f.getName()+f.length(); 
       byte[] b = data.getBytes(); 

       sendBytes(b, 0, b.length); 


       dos.flush(); 
       bos.flush(); 

       bis.close(); 

       dos.close(); 

       //clientProcessingPool.submit(new ServerTask(socket)); 
      } catch (IOException ex) { 
       Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex);   } finally { 

      } 

     } 
    }; 

    Thread serverThread = new Thread(serverTask); 
    serverThread.start(); 

    public void sendBytes(byte[] myByteArray, int start, int len) throws IOException { 
    if (len < 0) { 
     throw new IllegalArgumentException("Negative length not allowed"); 
    } 
    if (start < 0 || start >= myByteArray.length) { 
     throw new IndexOutOfBoundsException("Out of bounds: " + start); 
    } 
// Other checks if needed. 

// May be better to save the streams in the support class; 
    // just like the socket variable. 
    OutputStream out = socket.getOutputStream(); 
    DataOutputStream dos = new DataOutputStream(out); 

    dos.writeInt(len); 
    if (len > 0) { 
     dos.write(myByteArray, start, len); 
    } 
} 

服務器代碼

private void acceptConnection() { 

    try { 

     final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10); 

     Runnable serverTask = new Runnable() { 
      @Override 
      public void run() { 
       try { 
        ServerSocket server = new ServerSocket(8080); 

        while (true) { 
         socket = server.accept(); 

         System.out.println("Got a client !"); 

         bis = new BufferedInputStream(socket.getInputStream()); 

         dis = new DataInputStream(socket.getInputStream()); 

         String data = readBytes().toString(); 

         System.out.println(data); 


         bos.close(); 

         dis.close(); 

         //clientProcessingPool.submit(new ClientTask(socket)); 
        } 
       } catch (IOException ex) { 
        System.out.println(ex.getMessage()); 
       } 
      } 
     }; 
     Thread serverThread = new Thread(serverTask); 
     serverThread.start(); 

    } catch (Exception io) { 

     io.printStackTrace(); 

    } 

} 

public byte[] readBytes() throws IOException { 
    // Again, probably better to store these objects references in the support class 
    InputStream in = socket.getInputStream(); 
    DataInputStream dis = new DataInputStream(in); 

    int len = dis.readInt(); 
    byte[] data = new byte[len]; 
    if (len > 0) { 
     dis.readFully(data); 
    } 
    return data; 
} 
+0

爲什麼使用'sendBytes()'而不是'bos.write()'? – mangusta

+0

我已經試過這種方式,它也有相同的結果,它的數據並非全部通過 –

+0

你怎麼知道它不是全部通過?你把這個字符串'f.getName()+ f.length();'與你在服務器上收到的那個比較了嗎?有什麼不同? – mangusta

回答

6

你混了很多東西:

  1. 變量開始的大部分時間用小寫字母,例如int port,int ipAddress
  2. 類以大寫字母開頭,例如客戶端,服務器
  3. 僅在套接字上打開一個Data *流。新DataInputStream類(socket.getInputStream())新的BufferedInputStream(socket.getInputStream()),但不能同時
  4. 如果同時需要,把它們連:新DataInputStream類(新的BufferedInputStream(socket.getInputStream()));
  5. KISS(保持簡短&簡單)
  6. 如果使用DataInputStream,則使用給定的發送對象和原語的功能,例如, sendUTF(),sendInt(),sendShort()等等...
  7. 爲您的變量名稱正確:servertask是客戶端線程?沒有
  8. 移動長匿名類一類新
  9. 不要使用8080端口,該端口是用於許多其他應用程序,將導致問題關於您例如我的建議

示例代碼:

服務器

public class Server implements Runnable { 
    private void acceptConnection() { 
      Thread serverThread = new Thread(this); 
      serverThread.start(); 
    } 

    @Override 
    public void run() { 
     try { 
      ServerSocket server = new ServerSocket(8081); 

      while (true) { 
       Socket socket = server.accept(); 
       System.out.println("Got a client !"); 

       // either open the datainputstream directly 
       DataInputStream dis = new DataInputStream(socket.getInputStream()); 
       // or chain them, but do not open two different streams: 
       // DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); 

       // Your DataStream allows you to read/write objects, use it! 
       String data = dis.readUTF(); 
       System.out.println(data); 

       dis.close(); 
       // in case you have a bufferedInputStream inside of Datainputstream: 
       // you do not have to close the bufferedstream 
      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     new Server().acceptConnection(); 
    } 
} 

描述:

  1. 主:創建一個新的服務器對象,這是一個Runnable
  2. acceptConnections:創建一個線程
  3. 運行:
    1. 打開一個ServerSocket
    2. 等待
    3. 開放只有一個連接流
    4. 讀取數據
    5. 關閉流並等待下一個連接

客戶

public class Client { 
    private static void sendToServer(String ipAddress, int port) throws UnknownHostException, IOException { 
     Socket socket = new Socket(ipAddress, port); 

     // same here, only open one stream 
     DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); 

     File f = new File("C:/Users/lukeLaptop/Downloads/RemoveWAT22.zip"); 
     String data = f.getName()+f.length(); 

     dos.writeUTF(data); 

     dos.flush(); 
     dos.close();  
    } 

    public static void main(String[] args) throws UnknownHostException, IOException { 
     Client.sendToServer("localhost", 8081); 
    } 
} 

描述(這一個是直線前進):

  1. 開放式插槽
  2. 開放的數據流中
  3. 發送數據
  4. 刷新並關閉
+0

謝謝,這實際上是相當豐富的,這是我第一次處理套接字,所以這是非常有幫助完整謝謝 –

相關問題