-1

I'm trying to send bytes and receive them over my socket connection but they're not doing either. I'm not sure if its a problem to do with the way i'm sending the bytes and strings or because I don't know how to read from server and client.

Client

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

}

Server

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

}

I think this problem might be with ByteArrayOutputStream. I wanted to use ByteBuffer because I heard it was much faster than normal DataInput and output streams.

2 Answers2

1

You are never calling Socket#read inside of your run method... If you dont read anything you dont have anything to work with in your loop, even when you are connected!

Take a look at this Tutorial about Sockets:

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

Dinh
  • 759
  • 5
  • 16
  • I get what you mean but what can I read I'm sending bytes not integers. the inputstream.read returns an int. –  Oct 05 '17 at 09:48
  • @OmarAhmed have a look at method description, read() reads byte and uses int to represent it, also you have method read(byte[]) which returns you number byte it read – user902383 Oct 05 '17 at 10:21
  • @user902383 I need to get bytearrays not bytes –  Oct 05 '17 at 10:28
  • 1
    A _bytearray_ is nothing but an array of bytes. – SCCC Oct 05 '17 at 10:36
0

Your server code should use ServerSocket instead of Socket. Socket is used to represent Client Socket objects in Java.

SCCC
  • 341
  • 3
  • 13
  • It does use ServerSocket the other socket in my handler is used to get client info (it connects fine) the issue is with sending and receiving byte arrays –  Oct 05 '17 at 10:29
  • The code you posted does not use ServerSocket anywhere. You will get help faster if you post the actual code of the server and a client. – SCCC Oct 05 '17 at 10:32