Socket handling in java

3 minute read

SocketHandler

import java.io.*;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.util.Arrays;

public class SocketHandler {
    // Socket instance
    public Socket socket = null;

    // Input/Output Stream
    private OutputStream output = null;
    private DataOutputStream outputdata = null;
    private InputStream input = null;
    private DataInputStream inputdata = null;

    private final static int MAX_DATA_SIZE = 999999;
    private byte[] recvBuff = new byte[MAX_DATA_SIZE];

    private int mSocketTimeout = 15*1000;

    private String mCharset = C.CHARSET_TO;

    /**
     * Creator
     * @param sock
     */
    public SocketHandler(Socket sock) {
        try {
            setSocket(sock);        
        } catch (Exception e) {
            LOG.error("setSocket Exception:" + e.getMessage());   
        }
    }

    /**
     * Set socket
     * @param sock
     * @throws Exception
     */
    public void setSocket(Socket sock) throws Exception {
        if (sock != null) {
            socket = sock;
            socket.setSoTimeout(mSocketTimeout); // Timeout
            input = socket.getInputStream();
            inputdata = new DataInputStream(input);
            output = socket.getOutputStream();
            outputdata = new DataOutputStream(output);
        }
    }

    /**
     * Set Charset
     * @param cs
     */
    public void setCharset(String cs) {
        mCharset = cs;
    }

    /**
     * Close resources
     * @throws Exception
     */
    public void close() throws Exception {
        if (input != null) input.close();
        if (inputdata != null) inputdata.close();

        if (output != null) output.close();
        if (outputdata != null) outputdata.close();

        if (socket != null) socket.close();
        socket = null;
    }

    /**
     * Send data
     * @param bytearr
     * @param offset
     * @param length
     */
    public int sendData(byte[] bytearr, int offset, int length)
    {
        LOG.debug(String.format("===> sendData() [datlen: %d] = [offset+length: %d]", bytearr.length, offset + length));

        try {
//            LOG.debug(String.format("===> sendData() [%d %d %d][%s]", bytearr.length, offset, length, new String(bytearr)));

            outputdata.write(bytearr, offset, length);
            outputdata.flush();
        }
        catch (IOException e) {
            LOG.error(String.format("sendData() IOException. offset:[%d], length:[%d], Msg[%s]", offset, length, e.getMessage()));
            return -1;
        }
        return 0;
    }

    /**
     * Receive data
     * @param offset
     * @param length
     * @param timeout
     * @return
     * @throws IOException
     */
    public String recvData(int offset, int length, int timeout) throws Exception {
        long startTime = System.currentTimeMillis();
        int recvBytes = 0;
        int recvCnt = 0;
        String str = "";

//        LOG.debug(String.format("recvData(%d)", length));

        if (length > recvBuff.length) {
            LOG.error(String.format("Length Limit Error: [%d][MAX: %d]", length, recvBuff.length));
            return null;
        }
        // Initialize memory
        Arrays.fill(recvBuff, 0, recvBuff.length, (byte) 0x00); // Null

        try {
            while (recvCnt < length) {
                recvBytes = input.read(recvBuff, recvCnt + offset, length - recvCnt);
                // ------------------------------------------------------------------------------------
                // Return when no data foun. BUT it's impossible to read only the requested length.
                // recvBytes = datarecv.read(recvBuff, idx+offset, datarecv.available());
                // ------------------------------------------------------------------------------------
                if (recvBytes == 0) {
                    Thread.sleep(1000);
                    continue;
                } else if(recvBytes < 0)
                {
                    LOG.info(String.format("recvData(%d) fail recvBytes[%d]", length, recvBytes));
                    throw new IOException("Disconnected..");
                }
                recvCnt += recvBytes;

//                LOG.debug(String.format("recvData(%d) read[%d][%d]", length, recvBytes, recvCnt));

                if (timeout != 0 && System.currentTimeMillis() - startTime > timeout)
                    throw new SocketTimeoutException("Timeout..");
            }
            str = new String(recvBuff, 0, recvCnt, mCharset);
        } catch (SocketTimeoutException ste) {
            throw ste;
        } catch (IOException ioe) {
            throw ioe;
        } catch (Exception e) {
            throw e;
        }

        return str;
    }

    /**
     * Receive data
     * @param offset
     * @param length
     * @param timeout
     * @return
     * @throws Exception
     */
    public byte[] recvDataByte(int offset, int length, int timeout) throws Exception {
        long startTime = System.currentTimeMillis();
        int recvBytes = 0;
        int recvCnt = 0;
        ByteBuffer byteBuffer = ByteBuffer.allocate(length);

        if (length > recvBuff.length) {
            LOG.error(String.format("Length Limit Error: [%d][MAX: %d]", length, recvBuff.length));
            return null;
        }

        try {
            while (recvCnt < length) {
                recvBytes = input.read(recvBuff, recvCnt + offset, length - recvCnt);
                // ------------------------------------------------------------------------------------
                // Return when no data foun. BUT it's impossible to read only the requested length.
                // recvBytes = datarecv.read(recvBuff, idx+offset, datarecv.available());
                // ------------------------------------------------------------------------------------
                if (recvBytes == 0) {
                    Thread.sleep(1000);
                    continue;
                } else if(recvBytes < 0)
                {
                    LOG.info(String.format("recvData(%d) fail recvBytes[%d]", length, recvBytes));
                    // 상대방 socket close()
                    throw new IOException("Disconnected..");
                }
                recvCnt += recvBytes;

//                LOG.debug(String.format("recvData(%d) read[%d][%d]", length, recvBytes, recvCnt));

                if (timeout != 0 && System.currentTimeMillis() - startTime > timeout)
                    throw new SocketTimeoutException("Timeout..");
            }
            byteBuffer.put(recvBuff, 0, recvBytes);

        } catch (SocketTimeoutException ste) {
            throw ste;
        } catch (IOException ioe) {
            throw ioe;
        } catch (Exception e) {
            throw e;
        }

        return byteBuffer.array();
    }
}

Tags:

Categories:

Updated:

Leave a comment