Hauptseite   Klassenhierarchie   Datenstrukturen   Auflistung der Dateien   Datenstruktur-Elemente   Datei-Elemente  

RNPacket.cpp

gehe zur Dokumentation dieser Datei
00001 /***********************************************************************************/
00002 /** \file               RNPacket.cpp
00003 **  \brief              Implementation zur Klasse RNPacket
00004 *************************************************************************************
00005 **  Autor:              Christian Roesch
00006 **
00007 **  Erstelldatum:       29.03.2002
00008 **  letzte Aenderung:   01.04.2002
00009 *************************************************************************************
00010 **  Die Klasse RNPacket sendet oder empfängt Daten in der Form von beliebigen
00011 **  Datenblöcken.
00012 ************************************************************************************/
00013 
00014 
00015 // includes
00016 #include "RNPacket.h"
00017 
00018 // Methoden-Definitionen
00019 
00020 /************************************************************************************
00021 **  Methode:            RNPacket::RNPacket
00022 ************************************************************************************/
00023 /** Konstruktor
00024 ***
00025 ************************************************************************************/
00026 RNPacket::RNPacket()
00027 {
00028     m_bInitialized=false;
00029     m_pmcCallBack=NULL;
00030     m_pvoidUserContext=NULL;
00031 
00032     m_iBufferUsage=0;
00033 }
00034 
00035 /************************************************************************************
00036 **  Methode:            RNPacket::~RNPacket
00037 ************************************************************************************/
00038 /** Destruktor
00039 ***
00040 ************************************************************************************/
00041 RNPacket::~RNPacket()
00042 {
00043     socketClose();
00044 }
00045 
00046 /************************************************************************************
00047 **  Methode:            RNPacket::initMessageCallBack
00048 ************************************************************************************/
00049 /** Initialisiert den MessageHandler Callback, bevor dies nicht geschehen ist, 
00050 *** können keine Aufrufe zu diesem Objekt Erfolg haben. Der UserContext wird bei 
00051 *** Aufruf der CallBack-Funktion übergeben, dies ist z.B. nützlich wenn mehrere 
00052 *** RNPackets zu den gleichen MessageHandler aufrufen. (kann aber auch einfach NULL 
00053 *** sein)
00054 ************************************************************************************/
00055 RNPRESULT RNPacket::initMessageCallBack(    PVOID pvoidUserContext,
00056                                             const PMESSAGECALLBACK pmcFoo)
00057 {
00058     if (pmcFoo == NULL)
00059     {
00060         return RNP_ERROR_INVALID_PARAM;
00061     }
00062 
00063     m_pmcCallBack=pmcFoo;
00064 
00065     m_pvoidUserContext=pvoidUserContext;
00066 
00067     m_bInitialized=true;
00068 
00069     return RNP_OK;
00070 }
00071 
00072 /************************************************************************************
00073 **  Methode:            RNPacket::recvMessage
00074 ************************************************************************************/
00075 /** Versucht Daten vom angegebenen Socket zu empfangen, wenn ein Packet empfangen
00076 *** werden kann, wird dieses der MessageCallBack übergeben.
00077 ************************************************************************************/
00078 RNPRESULT RNPacket::recvMessage(void)
00079 {
00080     if (m_bInitialized == false)
00081     {
00082         return RNP_ERROR_NOT_INITIALIZED;
00083     }
00084 
00085     bool bReadable;
00086 
00087     if (!m_RNSSocket.isReadable(bReadable,0))
00088     {
00089         return RNP_ERROR_SOCKET;
00090     }
00091 
00092     if (!bReadable)
00093     {
00094         return RNP_SOCKET_NOT_READABLE;
00095     }
00096 
00097     WORD wLength;
00098 
00099     if (m_iBufferUsage<c_iMaxPacketLength)
00100     {
00101         int iBytesReceived=c_iMaxPacketLength-m_iBufferUsage;
00102 
00103         if(!m_RNSSocket.receive(    m_pcBuffer+m_iBufferUsage,
00104                                     &iBytesReceived))
00105         {
00106             return RNP_SOCKET_NOT_CONNECTED;
00107         }
00108 
00109         m_iBufferUsage=+iBytesReceived;
00110 
00111         if (iBytesReceived==0)
00112         {
00113             return RNP_SOCKET_NOT_CONNECTED;
00114         }
00115     }
00116 
00117     while (true)
00118     {
00119         if (m_iBufferUsage<2)
00120         {
00121             // noch nichtmal die 2 Header Bytes sind da...
00122             return RNP_OK;
00123         }
00124         
00125         wLength=*(WORD*)m_pcBuffer;
00126         
00127         if (m_iBufferUsage<2+wLength)
00128         {
00129             // kein komplettes Paket da
00130             return RNP_OK;
00131         }
00132         
00133         // Speicher für gesamtes Paket besorgen und abholen
00134         void* pvoidData= new char[wLength];
00135         
00136         // Speicher holen fehlgeschlagen?!
00137         if (pvoidData==NULL)
00138         {
00139             return RNP_ERROR_UNDEFINED; // sollte _nie_ vorkommen
00140         }
00141         
00142         // Paket in den Speicher kopieren
00143         memcpy(pvoidData,(void*)((char*)m_pcBuffer+2),wLength);
00144         
00145         // Bufferlänge anpassem
00146         m_iBufferUsage-=(wLength+2);
00147         
00148         if (m_iBufferUsage>0)
00149         {
00150             // ein Teil des nächsten Pakets ist schon da
00151             memmove((void*)m_pcBuffer,(void*)(m_pcBuffer+(wLength+2)),m_iBufferUsage);
00152         }
00153         
00154         // den Buffer an den MessageHandler schicken
00155         RNPRESULT rnpTmp;
00156         
00157         rnpTmp=m_pmcCallBack(m_pvoidUserContext,pvoidData, wLength);
00158         
00159         if (rnpTmp == RNP_BUFFER_RETURNED)
00160         {
00161             delete pvoidData;
00162         }
00163     }
00164 
00165     //  return RNP_OK;
00166 }
00167 
00168 /************************************************************************************
00169 **  Methode:            RNPacket::sendMessage
00170 ************************************************************************************/
00171 /** Verschickt ein Paket mit der entsprechenden Grösse über den Socket. Wird nicht
00172 *** alles gesendet ist davon auszugehen, das die Verbindung unterbrochen ist, da ein
00173 *** Paket kaputt ist.
00174 ************************************************************************************/
00175 RNPRESULT RNPacket::sendMessage(void* pvoidData, WORD wBufferSize)
00176 {
00177     if (pvoidData == NULL)
00178     {
00179         return RNP_ERROR_INVALID_PARAM;
00180     }
00181     
00182     if (wBufferSize == 0)
00183     {
00184         return RNP_ERROR_INVALID_PARAM;
00185     }
00186     
00187     if (m_bInitialized == false)
00188     {
00189         return RNP_ERROR_NOT_INITIALIZED;
00190     }
00191 
00192     bool bWriteable;
00193 
00194     if (!m_RNSSocket.isWriteable(bWriteable,0))
00195     {
00196         return RNP_ERROR_SOCKET;
00197     }
00198 
00199     if (!bWriteable)
00200     {
00201         return RNP_SOCKET_NOT_WRITEABLE;
00202     }
00203 
00204     //Packet und Längeninfo zusammenpacken
00205     int iLength=2+wBufferSize; 
00206 
00207     char* pcBuffer= new char[iLength];
00208 
00209     *((WORD*)pcBuffer)=wBufferSize;
00210 
00211     memcpy((void*)(pcBuffer+2),pvoidData,wBufferSize);
00212 
00213     if (!m_RNSSocket.send(pcBuffer, &iLength))
00214     {
00215         return RNP_ERROR_SOCKET;
00216     }
00217 
00218     return RNP_OK;
00219 }
00220 
00221 /************************************************************************************
00222 **  Methode:            RNPacket::socketConnect
00223 ************************************************************************************/
00224 /** Versucht eine Verbindung zur angegebenen Adresse aufzubauen.
00225 *** 
00226 ************************************************************************************/
00227 RNPRESULT RNPacket::socketConnect(  char* pcDestName, 
00228                                     int iPort ,
00229                                     int iAdressFamily /* = AF_INET  */, 
00230                                     int iType /* = SOCK_STREAM */, 
00231                                     int iProtocol /* = IPPROTO_IP */    )
00232 {
00233     if (m_bInitialized == false)
00234     {
00235         return RNP_ERROR_NOT_INITIALIZED;
00236     }
00237 
00238     if(!m_RNSSocket.create(iAdressFamily, iType, iProtocol))
00239     {
00240         return RNP_ERROR_SOCKET;
00241     }
00242 
00243     if(!m_RNSSocket.connect(pcDestName, iPort, iAdressFamily))
00244     {
00245         return RNP_SOCKET_NOT_CONNECTED;
00246     }
00247 
00248     return RNP_OK;
00249 }
00250 
00251 /************************************************************************************
00252 **  Methode:            RNPacket::socketAccept
00253 ************************************************************************************/
00254 /** Die Methode akzeptiert eine eingehende Verbinding, die am Listener registriert
00255 *** wird.
00256 ************************************************************************************/
00257 RNPRESULT RNPacket::socketAccept(RNSocket* psocketListener)
00258 {
00259     if (m_bInitialized == false)
00260     {
00261         return RNP_ERROR_NOT_INITIALIZED;
00262     }
00263     
00264     bool bReadable;
00265 
00266     if(!psocketListener->isReadable(bReadable,100))
00267     {
00268         return RNP_ERROR_SOCKET;
00269     }
00270 
00271     if (!bReadable)
00272     {
00273         return RNP_SOCKET_NOT_CONNECTED;
00274     }
00275 
00276     if(!psocketListener->accept(m_RNSSocket))
00277     {
00278         return RNP_SOCKET_NOT_CONNECTED;
00279     }
00280 
00281     return RNP_OK;
00282 }
00283 
00284 /************************************************************************************
00285 **  Methode:            RNPacket::socketClose
00286 ************************************************************************************/
00287 /** Schliesst den Socket.
00288 ***
00289 ************************************************************************************/
00290 RNPRESULT RNPacket::socketClose(void)
00291 {
00292     if (m_bInitialized == false)
00293     {
00294         return RNP_ERROR_NOT_INITIALIZED;
00295     }
00296 
00297     if(!m_RNSSocket.close())
00298     {
00299         return RNP_ERROR_SOCKET;
00300     }
00301 
00302     return RNP_OK;
00303 }
00304 
00305 /************************************************************************************
00306 **  Ende der Datei:     RNPacket.cpp
00307 ************************************************************************************/

Erzeugt am Thu Apr 4 17:13:57 2002 für Rechnernetze-Aufgabe1 von doxygen1.2.13.1 geschrieben von Dimitri van Heesch, © 1997-2001