diff --git a/build.xml b/build.xml index d43702db3..6b768ab30 100644 --- a/build.xml +++ b/build.xml @@ -22,7 +22,7 @@ - + @@ -46,7 +46,7 @@ + debug="on" sourcepath="" srcdir="${src.dir}"> diff --git a/dist/ttorrent-1.0.2.jar b/dist/ttorrent-1.0.3.jar similarity index 81% rename from dist/ttorrent-1.0.2.jar rename to dist/ttorrent-1.0.3.jar index f33b38098..8e1efc455 100644 Binary files a/dist/ttorrent-1.0.2.jar and b/dist/ttorrent-1.0.3.jar differ diff --git a/src/com/turn/ttorrent/client/Client.java b/src/com/turn/ttorrent/client/Client.java index a0f01d9f3..29fe8d503 100644 --- a/src/com/turn/ttorrent/client/Client.java +++ b/src/com/turn/ttorrent/client/Client.java @@ -28,6 +28,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketException; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.ClosedByInterruptException; @@ -404,6 +405,7 @@ private SharingPeer getOrCreatePeer(byte[] peerId, String ip, int port) { if (search.hasPeerId()) { peer = this.peers.get(search.getHostIdentifier()); if (peer != null) { + // Set peer ID for perviously known peer. peer.setPeerId(search.getPeerId()); this.peers.remove(peer.getHostIdentifier()); @@ -413,10 +415,13 @@ private SharingPeer getOrCreatePeer(byte[] peerId, String ip, int port) { } peer = new SharingPeer(ip, port, search.getPeerId(), this.torrent); - this.peers.putIfAbsent(peer.getHostIdentifier(), peer); + this.peers.putIfAbsent(peer.hasPeerId() + ? peer.getHexPeerId() + : peer.getHostIdentifier(), + peer); + logger.trace("Created new peer " + peer + "."); } - peer.register(this.torrent); return peer; } @@ -644,16 +649,23 @@ private void processAnnouncedPeer(byte[] peerId, String ip, int port) { public void handleNewPeerConnection(Socket s, byte[] peerId) { SharingPeer peer = this.getOrCreatePeer(peerId, s.getInetAddress().getHostAddress(), s.getPort()); - this.connected.put(peer.getHexPeerId(), peer); - synchronized (peer) { - peer.register(this); - peer.bind(s); - } + try { + synchronized (peer) { + peer.register(this); + peer.bind(s); + } - logger.info("New peer connection with " + peer + - " [" + this.connected.size() + "/" + - this.peers.size() + "]."); + this.connected.put(peer.getHexPeerId(), peer); + peer.register(this.torrent); + logger.info("New peer connection with " + peer + + " [" + this.connected.size() + "/" + + this.peers.size() + "]."); + } catch (SocketException se) { + this.connected.remove(peer.getHexPeerId()); + logger.warn("Could not handle new peer connection " + + "with " + peer + ": " + se.getMessage()); + } } diff --git a/src/com/turn/ttorrent/client/peer/PeerExchange.java b/src/com/turn/ttorrent/client/peer/PeerExchange.java index 35351ce44..c3b509447 100644 --- a/src/com/turn/ttorrent/client/peer/PeerExchange.java +++ b/src/com/turn/ttorrent/client/peer/PeerExchange.java @@ -23,6 +23,7 @@ import java.io.OutputStream; import java.lang.InterruptedException; import java.net.Socket; +import java.net.SocketException; import java.nio.ByteBuffer; import java.text.ParseException; import java.util.BitSet; @@ -80,11 +81,14 @@ class PeerExchange { * @param socket The connected socket to the peer. */ public PeerExchange(SharingPeer peer, SharedTorrent torrent, - Socket socket) { + Socket socket) throws SocketException { this.peer = peer; this.torrent = torrent; this.socket = socket; + // Set the socket read timeout. + this.socket.setSoTimeout(PeerExchange.KEEP_ALIVE_FOR_MINUTES*60*1000); + this.listeners = new HashSet(); this.sendQueue = new LinkedBlockingQueue(); @@ -227,7 +231,7 @@ public void run() { } } catch (IOException ioe) { logger.trace("Could not read message from " + peer + - ": " + ioe.getMessage()); + ": " + ioe.getMessage(), ioe); peer.unbind(true); } } @@ -244,12 +248,8 @@ public void run() { */ private class OutgoingThread extends Thread { - private long lastMessageTime; - @Override public void run() { - this.lastMessageTime = 0; - try { OutputStream os = socket.getOutputStream(); @@ -263,20 +263,11 @@ public void run() { TimeUnit.MINUTES); if (message == null) { - // If we have to send a keep alive, check it hasn't - // been more than KEEP_ALIVE_FOR_MINUTES since the - // last message, otherwise we can consider this - // peer as dead. - if (System.currentTimeMillis() - - this.lastMessageTime > - PeerExchange.KEEP_ALIVE_FOR_MINUTES) { - peer.unbind(true); + if (stop) { return; - } else { - message = Message.KeepAliveMessage.craft(); } - } else { - this.lastMessageTime = 0; + + message = Message.KeepAliveMessage.craft(); } logger.trace("Sending " + message + " to " + peer + "."); @@ -287,7 +278,7 @@ public void run() { } } catch (IOException ioe) { logger.trace("Could not send message to " + peer + - ": " + ioe.getMessage()); + ": " + ioe.getMessage(), ioe); peer.unbind(true); } } diff --git a/src/com/turn/ttorrent/client/peer/SharingPeer.java b/src/com/turn/ttorrent/client/peer/SharingPeer.java index 52326b8be..fc2dbe660 100644 --- a/src/com/turn/ttorrent/client/peer/SharingPeer.java +++ b/src/com/turn/ttorrent/client/peer/SharingPeer.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.net.Socket; +import java.net.SocketException; import java.nio.ByteBuffer; import java.util.BitSet; import java.util.Comparator; @@ -235,7 +236,9 @@ public synchronized boolean isSeed() { * * @param socket The connected socket for this peer. */ - public synchronized void bind(Socket socket) { + public synchronized void bind(Socket socket) throws SocketException { + this.unbind(true); + this.exchange = new PeerExchange(this, this.torrent, socket); this.exchange.register(this); @@ -367,6 +370,10 @@ private synchronized void requestNextBlocks() { * @param message The PIECE message received. */ private synchronized void removeBlockRequest(Message.PieceMessage message) { + if (this.requests == null) { + return; + } + for (Message.RequestMessage request : this.requests) { if (request.getPiece() == message.getPiece() && request.getOffset() == message.getOffset()) {