Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | Related Pages | Examples

packetsender.h

00001 /***************************************************************************
00002  * The contents of this file are subject to the Mozilla Public             *
00003  * License Version 1.1 (the "License"); you may not use this file          *
00004  * except in compliance with the License. You may obtain a copy of         *
00005  * the License at http://www.mozilla.org/MPL/                              *
00006  *                                                                         *
00007  * Software distributed under the License is distributed on an "AS         *
00008  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or              *
00009  * implied. See the License for the specific language governing            *
00010  * rights and limitations under the License.                               *
00011  *                                                                         *
00012  * The Original Code is Game Network Framework (GaNeF).                    *
00013  *                                                                         *
00014  * The Initial Developers of the Original Code are                         *
00015  * Lars Langer and Emanuel Greisen                                         *
00016  * Copyright (C) 2005. Lars Langer & Emanuel Greisen                       *
00017  * All Rights Reserved.                                                    *
00018  *                                                                         *
00019  * Contributor(s):                                                         *
00020  *   none yet....                                                          *
00021  *                                                                         *
00022  ***************************************************************************/
00023 #ifndef PACKETSENDER_H
00024 #define PACKETSENDER_H
00025 
00026 #include <ptypes.h>
00027 #include <pinet.h>
00028 
00029 USING_PTYPES;
00030 
00031 
00032 template<class PacketType>
00033 class Queue;
00034 class FrameworkPacket;
00035 template<class PacketType, class SocketType>
00036 class Framework;
00037 template<class PacketType, class SocketType>
00038 int sendTo(PacketType * pack, SocketType * socket);
00039 
00040 /**
00041  * @ingroup Common
00042  * @brief This class sends packets across the network.
00043  * It runs in it's own thread, constantly trying to empty the outqueue. Since the outqueue works as a semaphore, we have a producer-consumer setup.
00044  *
00045  * @author Lars Langer and Emanuel Greisen
00046 */
00047 template<class PacketType, class SocketType>
00048 class PacketSender : public thread
00049 {
00050 private:
00051    Framework<PacketType, SocketType> * framework;
00052    unsigned long packets_sent, bytes_sent;
00053    Queue<PacketType> * queue;
00054    SocketType * socket;
00055    bool _running;
00056    mutex & m_mutex;
00057 
00058 public:
00059    PacketSender(SocketType * socket, Queue<PacketType> * queue, mutex & pendingackmutex, Framework<PacketType, SocketType> * framework);
00060    ~PacketSender();
00061 
00062 private:
00063    void sendPacket(PacketType * pack);
00064 
00065 public:
00066    void startSending();
00067    inline unsigned int bytesSent() const { return bytes_sent; };
00068    inline unsigned int packetsSent() const { return packets_sent; };
00069    void sendPacketSync(PacketType * pack);
00070 
00071 public:
00072    virtual void execute();
00073    virtual void cleanup();
00074 
00075 };
00076 
00077 
00078 template<class PacketType, class SocketType>
00079 PacketSender<PacketType, SocketType>::PacketSender(SocketType * socket, Queue<PacketType> * queue, mutex & pendingackmutex, Framework<PacketType, SocketType> * framework) :
00080    socket(socket),
00081    queue(queue),
00082    m_mutex(pendingackmutex),
00083    _running(false),
00084    packets_sent(0),
00085    bytes_sent(0),
00086    framework(framework),
00087    thread(false)
00088 {
00089 
00090 }
00091 
00092 template<class PacketType, class SocketType>
00093 PacketSender<PacketType, SocketType>::~PacketSender()
00094 {
00095 }
00096 
00097 template<class PacketType, class SocketType>
00098 void PacketSender<PacketType, SocketType>::sendPacketSync( PacketType * pack )
00099 {
00100    if(get_running())
00101       throw new FrameworkError("You cannot use sendPacketSync when the sender is running");
00102    std::cout << "About to send NOW" << std::endl;
00103    sendPacket(pack);
00104 }
00105 
00106 
00107 template<class PacketType, class SocketType>
00108 void PacketSender<PacketType, SocketType>::sendPacket( PacketType * pack )
00109 {
00110    scopelock mutexed_method(m_mutex); // Make sure we are the only one sending now, and that no ACKs are registered while we are sending
00111 
00112    if(!pack->peer.initialized)
00113    {
00114       std::cerr << "Packet " << * pack << " does not have a valid peer.host\n";
00115    }
00116 
00117    // If the pack was acknowledged, then we should do the dirty job of deleting the packet
00118    if(pack->isAborted())
00119    {
00120       delete pack;
00121    }
00122    else
00123    {
00124       // Then we add this packet to pending acks, if its reliable
00125       if(pack->isReliable())
00126       {
00127          // This is a special case, since these packets did not get a sequence number when entering the queue.
00128          // They were most likely generated inside a presending-chain.
00129          if(pack->isPluginPacket())
00130          {
00131             framework->addPluginSequenceNumber(pack);
00132          }
00133 
00134          // Add the pending ACK
00135          framework->addPendingAck(pack, true);
00136       }
00137 
00138       //std::cout << "Sending "<<pack->getSize()<<" bytes of data to "<<pack->peer.host<<":"<<pack->peer.port << std::endl;
00139       pack->makeSendReady();
00140       if(!pack->isReliable())
00141       {
00142          //std::cout << "Sending(unreliable):" << pack->getSequenceNumber() << std::endl;
00143       }
00144       int bs = sendTo(pack, socket);
00145       //std::cout << " [" << bs << " bytes sent]" << std::endl;
00146       if(bs != -1)
00147       {
00148          if(pack->isReliable())
00149          {
00150             pack->setStateSent();
00151             framework->sentReliablePacket(pack); // Used to track heartbeating
00152          }
00153          else
00154          {
00155             // Well since it was unreliable we must assume the net will give it a chance...
00156             // out there in the great wide world !
00157             delete pack;
00158          }
00159          bytes_sent += bs;
00160       }
00161       else
00162       {
00163          std::cerr << "PANIX: we could not send a packet, we got -1 for return value on bytes sent"  << std::endl;
00164       }
00165    }
00166 }
00167 
00168 // Special Client version of sender
00169 template<class PacketType>
00170 int sendTo(PacketType * pack, ipmessage * socket)
00171 {
00172    int bs;
00173    try
00174    {
00175       socket->send(pack->getData(), pack->getSize());
00176       bs = pack->getSize();
00177    }
00178    catch(estream * err)
00179    {
00180       perr.putf("Error Sending: %s\n", pconst(err->get_message()));
00181       delete err;
00182       return -1;
00183    }
00184    return bs;
00185 }
00186 
00187 // Special Server version of sender
00188 template<class PacketType>
00189 int sendTo(PacketType * pack, ipmsgserver * socket)
00190 {
00191    int bs;
00192    try
00193    {
00194       socket->sendto(pack->getData(), pack->getSize(), pack->peer.host, pack->peer.port);
00195       bs = pack->getSize();
00196    }
00197    catch(estream * err)
00198    {
00199       std::cerr << "Error Sending> " << pconst(err->get_message()) << std::endl;
00200       std::cerr << "Packet> " << *pack << std::endl;
00201       std::cerr << "Socket is set to " << pconst(socket->get_host()) << ":" << socket->get_port() << std::endl;
00202       delete err;
00203       return -1;
00204    }
00205    return bs;
00206 }
00207 
00208 template<class PacketType, class SocketType>
00209 void PacketSender<PacketType, SocketType>::startSending( )
00210 {
00211    _running = true;
00212    start();
00213 }
00214 
00215 template<class PacketType, class SocketType>
00216 void PacketSender<PacketType, SocketType>::execute( )
00217 {
00218    while(_running)
00219    {
00220       //std::cout << "queue->size():" << queue->size() << std::endl;
00221       PacketType * p = queue->next();
00222       //std::cout << "Sending "<<p->getSize()<<" bytes of data to "<<p->peer.host<<":"<<p->peer.port;
00223       sendPacket(p);
00224       packets_sent++;
00225    }
00226 }
00227 
00228 template<class PacketType, class SocketType>
00229 void PacketSender<PacketType, SocketType>::cleanup( )
00230 {
00231    std::cout << "Sender has been terminated" << std::endl;
00232 }
00233 
00234 
00235 
00236 
00237 
00238 #endif

Generated on Mon Feb 6 12:24:50 2006 for Ganef by  doxygen 1.4.4