Package org.jmule.core.networkmanager

Source Code of org.jmule.core.networkmanager.JMServerConnection$SenderThread

/*
*  JMule - Java file sharing client
*  Copyright (C) 2007-2009 JMule team ( jmule@jmule.org / http://jmule.org )
*
*  Any parts of this program derived from other projects, or contributed
*  by third-party developers are copyrighted by their respective authors.
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*
*/
package org.jmule.core.networkmanager;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.zip.DataFormatException;

import org.jmule.core.JMException;
import org.jmule.core.JMThread;
import org.jmule.core.configmanager.ConfigurationManager;
import org.jmule.core.edonkey.E2DKConstants;
import org.jmule.core.edonkey.packet.Packet;
import org.jmule.core.utils.JMuleZLib;
import org.jmule.core.utils.Misc;

/**
* Created on Aug 20, 2009
* @author binary256
* @author javajox
* @version $Revision: 1.7 $
* Last changed by $Author: binary255 $ on $Date: 2009/11/17 10:04:46 $
*/
public class JMServerConnection extends JMConnection {

  private JMuleSocketChannel jm_socket_channel;
 
  private JMThread connecting_thread;
  private JMThread receiver_thread;
 
  private SenderThread sender_thread;
  private Queue<Packet> send_queue = new ConcurrentLinkedQueue<Packet>();
 
  private InetSocketAddress remote_inet_socket_address;
   
  private InternalNetworkManager _network_manager = (InternalNetworkManager) NetworkManagerSingleton.getInstance();
   
  private ConnectionStatus connection_status = ConnectionStatus.DISCONNECTED; 
 
  JMServerConnection(String ipAddress, int port) {
    remote_inet_socket_address = new InetSocketAddress(ipAddress, port);
  }
 
  JMServerConnection(InetSocketAddress remoteInetSocketAddress) {
    remote_inet_socket_address = remoteInetSocketAddress;
  }
 
  String getIPAddress() {
    return remote_inet_socket_address.getAddress().getHostAddress();
  }
 
  int getPort() {
    return remote_inet_socket_address.getPort();
  }
 
  ConnectionStatus getStatus() {
    return connection_status;
  }
 
  void send(Packet packet) throws JMException {
    if (connection_status != ConnectionStatus.CONNECTED)
      throw new JMException("Server connection not open to " + remote_inet_socket_address);
    send_queue.add(packet);
    if (sender_thread.isSleeping())
      sender_thread.wakeUp();
  }
 
  private void sendPacket(Packet packet) throws Exception {
    if (!E2DKConstants.SERVER_PACKETS_NOT_ALLOWED_TO_COMPRESS
        .contains(packet.getCommand())
        && (packet.getLength() >= E2DKConstants.PACKET_SIZE_TO_COMPRESS)) {
      byte op_code = packet.getCommand();
      ByteBuffer raw_data = Misc.getByteBuffer(packet.getLength()-1-4-1);
      ByteBuffer data = packet.getAsByteBuffer();
      data.position(1 + 4 + 1);
      raw_data.put(data);
      raw_data.position(0);
      raw_data = JMuleZLib.compressData(raw_data);
      packet = new Packet(raw_data.capacity(), E2DKConstants.PROTO_EMULE_COMPRESSED_TCP);
      packet.setCommand(op_code);
      raw_data.position(0);
      packet.insertData(raw_data);
    }
    if(jm_socket_channel.write(packet.getAsByteBuffer()) == -1 )
        notifyDisconnect();
  }
 
  void connect() {
    connecting_thread = new JMThread() {
      public void run() {     
        try {
          connection_status = ConnectionStatus.CONNECTING;
          SocketChannel channel = SocketChannel.open();
         
          jm_socket_channel = new JMuleSocketChannel(channel);
         
          jm_socket_channel.connect(remote_inet_socket_address, ConfigurationManager.SERVER_CONNECTING_TIMEOUT);
         
          connection_status = ConnectionStatus.CONNECTED;
          send_queue.clear();
          sender_thread = new SenderThread();
          sender_thread.start();
         
          createReceiverThread();
         
          receiver_thread.start();
         
          _network_manager.serverConnected();
         
        } catch (Throwable cause) {
          cause.printStackTrace();
          connection_status = ConnectionStatus.DISCONNECTED;
          _network_manager.serverConnectingFailed(cause);
        }
       
      }
     
      public void JMStop() {
      }
     
    };
   
    connecting_thread.start();
  }
 
  void disconnect() throws NetworkManagerException {
    if (connection_status == ConnectionStatus.CONNECTED) {
      try {
        jm_socket_channel.close();
        connection_status = ConnectionStatus.DISCONNECTED;
      } catch (IOException cause) {
        throw new NetworkManagerException(cause);
      }
      receiver_thread.JMStop();
      sender_thread.JMStop();
    }
   
    if (connection_status == ConnectionStatus.CONNECTING) {
      try {
        jm_socket_channel.close();
        connection_status = ConnectionStatus.DISCONNECTED;
      } catch (IOException cause) {
        throw new NetworkManagerException(cause);
      }
    }
  }
 
 
  private void notifyDisconnect() {
    _network_manager.serverDisconnected();
   
    receiver_thread.JMStop();
    sender_thread.JMStop();
  }
 
 
  private void createReceiverThread() {
    receiver_thread = new JMThread() {
      
      private boolean stop_thread = false;
     
      public void run() {
        while(!stop_thread) {
          try {
            PacketReader.readServerPacket(jm_socket_channel);
          } catch (JMEndOfStreamException e) {
            e.printStackTrace();
            notifyDisconnect();
          } catch (IOException e) {
            e.printStackTrace();
          } catch (UnknownPacketException e) {
            e.printStackTrace();
          } catch (DataFormatException e) {
            e.printStackTrace();
          } catch (MalformattedPacketException e) {
            e.printStackTrace();
          }
        }
         
       
      }
     
      public void JMStop() {
        stop_thread = true;
      }
    };
  }
 
  private class SenderThread extends JMThread {
    private boolean loop = true;
    private boolean is_sleeping = false;
    public SenderThread() {
      super("Server packet sender to " + remote_inet_socket_address);
    }
   
    public void run() {
      while(loop) {
        is_sleeping = false;
        if (!jm_socket_channel.isConnected()) break;
        if (send_queue.isEmpty()) {
          is_sleeping = true;
          synchronized(this) {
            try {
              this.wait();
            } catch (InterruptedException e) {
            }
          }
          continue;
        }
        Packet packet = send_queue.poll();
        try {
          sendPacket(packet);
        } catch (Exception e) {
          if (!jm_socket_channel.isConnected()) break;
        }
      }
    }
   
    public boolean isSleeping() {return is_sleeping; }
    public void wakeUp() {
      synchronized (this) {
        this.notify();
      }
    }
    public void JMStop() {
      loop = false;
      synchronized (this) {
        this.notify();
      }
    }
   
  }
 
}
TOP

Related Classes of org.jmule.core.networkmanager.JMServerConnection$SenderThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.