package com.silicondust.libhdhomerun; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.InetAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import com.silicondust.libhdhomerun.HDHomerun_Sock.hdhomerun_sock_t; public class HDHomerun_sock_t_tcp implements hdhomerun_sock_t { SocketChannel channel; boolean mValid = false; public HDHomerun_sock_t_tcp(SocketAddress remoteAddr, int sendBufferSize, int recBufferSize, int timeout) throws IOException { channel = SocketChannel.open(); channel.configureBlocking(false); if(timeout == 0) timeout = HDHomerun_Sock.DEFAULT_NONBLOCKING_TIMEOUT; channel.socket().setSoTimeout(timeout); if(sendBufferSize > 0) channel.socket().setSendBufferSize(sendBufferSize); if(recBufferSize > 0) channel.socket().setReceiveBufferSize(recBufferSize); channel.connect(remoteAddr); while(!channel.finishConnect()) { if(!channel.isConnectionPending()) break; } mValid = channel.isConnected(); } @Override public boolean addGroup(InetAddress multicastIP) { return false; } @Override public boolean dropGroup(InetAddress multicastIP) { return false; } @Override public boolean isValid() { return mValid; } @Override public void closeSocket() throws Exception{ channel.close(); } @Override public SocketAddress getSocketAddr() { return channel.socket().getLocalSocketAddress(); } @Override public int getSocketPort() { return channel.socket().getPort(); } @Override public int send(byte[] data, int startIndex, int length, int timeout) throws IOException{ int oldtimeout = channel.socket().getSoTimeout(); if(timeout != oldtimeout) { if(timeout == 0) timeout = HDHomerun_Sock.DEFAULT_NONBLOCKING_TIMEOUT; channel.socket().setSoTimeout(timeout); } int packetSize = channel.socket().getSendBufferSize(); int bytesWritten = 0; int bytesLeft = length; while(true) { if(bytesLeft < packetSize) packetSize = bytesLeft; ByteBuffer buff = ByteBuffer.wrap(data, startIndex + bytesWritten, packetSize); channel.write(buff); bytesLeft -= packetSize; bytesWritten += packetSize; if(bytesLeft == 0) break; } if(timeout != oldtimeout) channel.socket().setSoTimeout(oldtimeout); return bytesWritten; } @Override public int sendto(byte[] data, int startIndex, int length, InetSocketAddress remoteAddr, int timeout) throws IOException { throw new IOException(); } @Override public InetSocketAddress recvfrom(byte[] data, int start, int length[], int timeout) throws IOException{ throw new IOException(); } @Override public boolean recv(byte[] data, int start, int length[], int timeout) throws IOException{ long endTime = HDHomerun_OS.getcurrenttime() + timeout; int packetSize = channel.socket().getReceiveBufferSize(); if(length[0] < packetSize) packetSize = length[0]; while (true) { ByteBuffer buff = ByteBuffer.wrap(data, start, length[0]); int ret = channel.read(buff); if (ret > 0) { length[0] = ret; return true; } if(endTime <= HDHomerun_OS.getcurrenttime()) return false; } } }