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