我的套接字不发送或接收bytearrays

时间:2017-10-05 09:27:16

标签: java sockets bytebuffer

我正在尝试发送字节并通过套接字连接接收它们,但它们也没有。我不确定它是否与我发送字节和字符串的方式有关,或者因为我不知道如何从服务器和客户端读取。

客户端

public class Client implements Runnable {

private Socket socket;
private ByteArrayOutputStream buffer;
private OutputStream output;
private Stage stage;

public Client() {
    try {
        this.socket = new Socket("localhost", 1337);
        this.socket.setTcpNoDelay(true);
        this.socket.setKeepAlive(true);
        this.output = this.socket.getOutputStream();
        InputStream input = this.socket.getInputStream();
        this.buffer = new ByteArrayOutputStream();
        Thread connection = new Thread(this);
        connection.start();
        this.sendPacket(0, ByteBuffer.allocate(16 + "TEST".length()).putInt("TEST".length()).put("TEST".getBytes(Constants.UTF8)).array());
        System.out.println("[CLIENT] Successfully connected to server.");
    } catch (Exception e) {
        IOUtils.output("[CLIENT] Error when connecting to server.");
        System.exit(1337);
    }
}

@Override
public void run() {
    try {
        while (this.connected()) {
            byte[] bytes = this.buffer.toByteArray();
            Constants.received += bytes.length;
            if (bytes.length < 8) return;
            ByteBuffer cbuf = ByteBuffer.wrap(bytes);
            int size = cbuf.getInt();
            int id = cbuf.getInt();
            if (bytes.length < size + 8) continue;
            byte[] data = Arrays.copyOfRange(bytes, 8, 8 + size);
            this.processPacket(id, data);
            this.buffer.close();
            (this.buffer = new ByteArrayOutputStream()).write(bytes, 8 + size, bytes.length - 8 - size);
        }
        System.out.println("[CLIENT] Disconnected from server.");
        System.exit(1337);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void processPacket(int id, byte[] bytes) {
    ByteBuffer data = ByteBuffer.wrap(bytes);
    if (id == 0) {
    System.out.println("Received packet from server with id 0");
    } else if (id == 1) {
    System.out.println("Received packet from server with id 1");
    }
}

private void sendPacket(int id, byte[] data) {
    try {
        ByteBuffer bytebuffer = ByteBuffer.allocate(8 + data.length);
        bytebuffer.putInt(data.length);
        bytebuffer.putInt(id);
        bytebuffer.put(data);
        byte[] bytes = bytebuffer.array();
        Constants.sent += bytes.length;
        this.output.write(bytes);
        this.output.flush();
    } catch (IOException e) {
        try {
            socket.close();
        } catch (IOException io) {
            IOUtils.output("[CLIENT] Error with client.");
            System.exit(1337);
        }
    }
}

private boolean connected() {
    return this.socket.isConnected() && !this.socket.isInputShutdown() && !this.socket.isOutputShutdown() && !this.socket.isClosed();   
}


}

ServerHandler

public class Handler implements Runnable {

private Socket socket;
private ByteArrayOutputStream buffer;
private OutputStream output;

public Handler(Socket socket) {
    this.socket = socket;
    try {
        this.output = this.socket.getOutputStream();
        InputStream input = this.socket.getInputStream();
        this.buffer = new ByteArrayOutputStream();
        Thread connection = new Thread(this);
        connection.start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void run() {
    try {
        IOUtils.output("[HANDLER] Connection from " + socket.getInetAddress());
        while (connected()) {
            byte[] bytes = this.buffer.toByteArray();
            if (bytes.length < 8) return;
            ByteBuffer buffer = ByteBuffer.wrap(bytes);
            int size = buffer.getInt();
            int id = buffer.getInt();
            if (bytes.length < size + 8) continue;
            byte[] data = Arrays.copyOfRange(bytes, 8, 8 + size);
            this.processPacket(id, data);
            this.buffer.close();
            (this.buffer = new ByteArrayOutputStream()).write(bytes, 8 + size, bytes.length - 8 - size);
        }
        IOUtils.output("[HANDLER] Client ended connection - " + socket.getInetAddress());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void sendPacket(int id, byte[] data) {
    try {
        ByteBuffer bytebuffer = ByteBuffer.allocate(8 + data.length);
        bytebuffer.putInt(data.length);
        bytebuffer.putInt(id);
        bytebuffer.put(data);
        byte[] bytes = bytebuffer.array();
        this.output.write(bytes);
        this.output.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void processPacket(int id, byte[] bytes) {
    ByteBuffer data = ByteBuffer.wrap(bytes);
    if (id == 0) {
        IOUtils.output("Recieved packet with id 0");
    } else if (id == 1) {
        //TODO: authenticate user.
    }
}

private boolean connected() {
    return this.socket.isConnected() && !this.socket.isInputShutdown() && !this.socket.isOutputShutdown() && !this.socket.isClosed();   
}

}

服务器

public class Server implements Runnable {

private int port;
private ServerSocket sock;

public Server(int port) {
    this.port = port;
    launch();
}

private void launch() {
    this.run();
}

@Override
public void run() {
    try {
        sock = new ServerSocket(port);
        System.out.println("[SERVER] Server started");
        while(!sock.isClosed()) {
            new Handler(sock.accept());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

我认为这个问题可能与ByteArrayOutputStream有关。我想使用ByteBuffer,因为我听说它比普通的DataInput和输出流快得多。

2 个答案:

答案 0 :(得分:1)

你永远不会在你的run方法中调用Socket #read ...如果你没有读任何东西,你在循环中没有任何东西可以处理,即使你已经连接了!

看看这个关于套接字的教程:

https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html

答案 1 :(得分:0)

您的服务器代码应使用ServerSocket而不是Socket。 Socket用于表示Java中的Client Socket对象。