package com.silicondust.libhdhomerun; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetSocketAddress; import java.net.MulticastSocket; import java.net.InetAddress; import java.net.SocketAddress; import java.net.SocketException; import com.silicondust.libhdhomerun.HDHomerun_Sock.hdhomerun_sock_t; public class HDHomerun_sock_t_udp implements hdhomerun_sock_t { // DatagramChannel channel = null;; MulticastSocket multiSocket = null; private boolean mValid = false; public HDHomerun_sock_t_udp(SocketAddress socketAddr, int sendBufferSize, int recBufferSize, boolean allowReuse) throws Exception { multiSocket = new MulticastSocket(socketAddr); multiSocket.setBroadcast(true); multiSocket.setReuseAddress(allowReuse); if(sendBufferSize > 0) multiSocket.setSendBufferSize(sendBufferSize); if(recBufferSize > 0) multiSocket.setReceiveBufferSize(recBufferSize); mValid = multiSocket.isBound(); } @Override public boolean addGroup(InetAddress groupAddr) { try { multiSocket.joinGroup(groupAddr); return true; } catch (IOException e) { return false; } } @Override public boolean dropGroup(InetAddress multicastIP) { try { multiSocket.leaveGroup(multicastIP); return true; } catch (IOException e) { return false; } } @Override public boolean isValid() { return mValid; } @Override public void closeSocket() throws Exception { multiSocket.close(); } public SocketAddress getSocketAddr() { return multiSocket.getLocalSocketAddress(); } @Override public int getSocketPort() { return multiSocket.getPort(); } @Override public int send(byte[] data, int startIndex, int length, int timeout) throws IOException{ throw new IOException(); } @Override public int sendto(byte[] data, int startIndex, int length, InetSocketAddress remoteAddr, int timeout) throws IOException { int oldtimeout = multiSocket.getSoTimeout(); if(timeout != oldtimeout) { if(timeout == 0) timeout = HDHomerun_Sock.DEFAULT_NONBLOCKING_TIMEOUT; multiSocket.setSoTimeout(timeout); } int bytesWritten = 0; int bytesLeft = length; int packetSize = multiSocket.getSendBufferSize(); while(true) { if(bytesLeft < packetSize) packetSize = bytesLeft; DatagramPacket p = new DatagramPacket(data, startIndex + bytesWritten, packetSize, remoteAddr); multiSocket.send(p); bytesWritten += packetSize; bytesLeft -= packetSize; if(bytesLeft == 0) break; } if(timeout != oldtimeout) multiSocket.setSoTimeout(oldtimeout); return bytesWritten; } @Override public boolean recv(byte[] data, int start, int length[], int timeout) throws IOException{ long endTime = HDHomerun_OS.getcurrenttime() + timeout; int packetSize = multiSocket.getReceiveBufferSize(); if(length[0] < packetSize) packetSize = length[0]; while (true) { DatagramPacket p = new DatagramPacket(data, start, length[0]); multiSocket.receive(p); int ret = p.getOffset(); if (ret > 0) { length[0] = ret; return true; } if(endTime <= HDHomerun_OS.getcurrenttime()) return false; } } @Override public InetSocketAddress recvfrom(byte[] data, int start, int length[], int timeout) throws IOException { int packetSize = multiSocket.getReceiveBufferSize(); multiSocket.setSoTimeout(10); if(length[0] < packetSize) packetSize = length[0]; while (true) { DatagramPacket p = new DatagramPacket(data, start, length[0]); try { multiSocket.receive(p); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { throw e; } int ret = p.getOffset(); if (ret > 0) { InetSocketAddress remoteAddr = (InetSocketAddress)p.getSocketAddress(); length[0] = ret; return remoteAddr; } } } }