/* * bitlet - Simple bittorrent library * Copyright (C) 2008 Alessandro Bahgat Shehata, Daniele Castagna * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.bitlet.wetorrent.peer; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.bitlet.wetorrent.Torrent; import org.bitlet.wetorrent.util.thread.InterruptableTasksThread; import org.bitlet.wetorrent.util.thread.ThreadTask; public class IncomingPeerListener extends InterruptableTasksThread { ServerSocket serverSocket; private Map<ByteBuffer, Torrent> torrents = new HashMap<ByteBuffer, Torrent>(); private Set<TorrentPeer> dispatchingPeers = new HashSet<TorrentPeer>(); private int port; private int receivedConnection = 0; public IncomingPeerListener(int port) { if (Torrent.verbose) { System.err.println("Binding incoming server socket"); } while (port < 65535 && serverSocket == null) { try { serverSocket = new ServerSocket(port); } catch (Exception e) { if (Torrent.verbose) { System.err.println("Cannot bind port " + port); } port++; } } if (serverSocket == null) { System.err.println("Cannot bind the incoming socket"); return; } this.port = port; final IncomingPeerListener incomingPeerListener = this; addTask(new ThreadTask() { public boolean execute() throws Exception { try { Socket socket = serverSocket.accept(); receivedConnection++; TorrentPeer peer = new TorrentPeer(socket, incomingPeerListener); dispatchingPeers.add(peer); peer.start(); } catch (SocketException e) { return false; } return true; } public void interrupt() { try { serverSocket.close(); } catch (Exception e) { } } public void exceptionCought(Exception e) { e.printStackTrace(); throw new RuntimeException(e); } }); } public int getPort() { return port; } public int getReceivedConnection() { return receivedConnection; } public synchronized void register(Torrent torrent) { torrents.put(ByteBuffer.wrap(torrent.getMetafile().getInfoSha1()), torrent); } public synchronized void unregister(Torrent torrent) { torrents.remove(ByteBuffer.wrap(torrent.getMetafile().getInfoSha1())); } public synchronized void peer(TorrentPeer dispatchingPeer) { dispatchingPeers.add(dispatchingPeer); } public synchronized boolean dispatchPeer(TorrentPeer dispatchingPeer, byte[] infoSha1) { dispatchingPeers.remove(dispatchingPeer); Torrent torrent = torrents.get(ByteBuffer.wrap(infoSha1)); if (torrent != null) { dispatchingPeer.setPeersManager(torrent.getPeersManager()); torrent.getPeersManager().offer(dispatchingPeer); return true; } else { return false; } } public void interrupt() { super.interrupt(); for (TorrentPeer p : dispatchingPeers) { p.interrupt(); } } public synchronized void removePeer(TorrentPeer peer) { dispatchingPeers.remove(peer); } }