使用客户端Java套接字同步服务器

Luk*_*ths 1 java sockets

目前我正在研究使用带有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);
    }
}
Run Code Online (Sandbox Code Playgroud)

服务器代码:

   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;
}
Run Code Online (Sandbox Code Playgroud)

Abs*_*ind 8

你混淆了很多东西:

  1. 变量大部分时间都以小写字母开头,例如int port,int ipAddress
  2. 类以大写字母开头,例如Client,Server
  3. 只在套接字上打开一个Data*流.新的DataInputStream(socket.getInputStream())新的BufferedInputStream(socket.getInputStream()),但不是两者都是
  4. 如果你需要两者,将它们链接起来:new DataInputStream(new BufferedInputStream(socket.getInputStream()));
  5. 吻(保持简短)
  6. 如果使用DataInputStream,则使用发送对象和基元的给定功能,例如sendUTF(),sendInt(),sendShort()等等......
  7. 将你的vars命名为right: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();
    }
}
Run Code Online (Sandbox Code Playgroud)

描述:

  1. main:创建一个新的Server Object,它是一个Runnable
  2. acceptConnections:创建一个Thread
  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);
    }
}
Run Code Online (Sandbox Code Playgroud)

说明(这是直截了当的):

  1. 打开插座
  2. 打开DataStream
  3. 发送数据
  4. 齐平并关闭