简体   繁体   English

将服务器与客户端Java套接字同步

[英]Synchronize server with client java sockets

Currently I am working on a server/client application which sends data using java with Runnable and threads . 目前,我正在使用服务器/客户端应用程序,该应用程序使用带有Runnablethread的 java发送数据。 The problem is that the client is sending the data and when the server starts to read it the client has already finished and closed the connection which on the server side only a partially of the data is arrived, can they be setup to be synchronized? 问题是客户端正在发送数据,并且当服务器开始读取数据时,客户端已经完成并关闭了服务器端仅一部分数据到达的连接,可以将它们设置为同步吗?

this is the client : 这是客户

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);
    }
}

server code : 服务器代码

   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;
}

You mixed up many things: 您混合了很多东西:

  1. Variables start most of the time with a lowercase letter, eg int port, int ipAddress 变量大部分时间以小写字母开头,例如int port,int ipAddress
  2. Classes start with a uppercase letter, eg Client, Server 类以大写字母开头,例如Client,Server
  3. only open one Data*stream on a socket. 仅在套接字上打开一个Data * stream。 new DataInputStream(socket.getInputStream()) or new BufferedInputStream(socket.getInputStream()), but not both 新的DataInputStream(socket.getInputStream()) 新的BufferedInputStream(socket.getInputStream()),但不能同时使用
  4. If you need both, chain them: new DataInputStream(new BufferedInputStream(socket.getInputStream())); 如果两者都需要,则将它们链接起来:new DataInputStream(new BufferedInputStream(socket.getInputStream()));
  5. KISS (Keep it short & simple) 吻(简短而简单)
  6. If you use a DataInputStream, then use the given functionality of sending objects and primitives, eg sendUTF(), sendInt(), sendShort(), and so on... 如果使用DataInputStream,则使用给定的发送对象和基元的功能,例如sendUTF(),sendInt(),sendShort()等。
  7. Name your vars right: servertask is a client thread? 正确命名您的vars:servertask是客户端线程吗? no 没有
  8. Move long anonymous classes to a new class 将较长的匿名课程移至新课程
  9. Don't use port 8080, this port is used for many other application and will cause problems 不要使用端口8080,该端口用于许多其他应用程序,会导致问题

example code regarding your example an my advices: 有关您的示例的示例代码是我的建议:

Server 服务器

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();
    }
}

description: 描述:

  1. main: create a new Server Object, which is a Runnable main:创建一个新的Server Object,它是一个Runnable
  2. acceptConnections: create a Thread acceptConnections:创建一个线程
  3. run: 跑:
    1. open a Serversocket 打开一个服务器套接字
    2. wait for a connection 等待连接
    3. open exactly one stream 只打开一个流
    4. read the Data 读取数据
    5. close the stream and wait for next connection 关闭流,等待下一次连接

Client 客户

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);
    }
}

description (This one is straight forward): 说明(简单明了):

  1. open socket 打开插座
  2. open DataStream 打开DataStream
  3. send Data 发送数据
  4. flush and close 冲洗并关闭

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM