2014-02-18 149 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

谢谢,这实际上是相当丰富的,这是我第一次处理套接字,所以这是非常有帮助完整谢谢 –

相关问题