Index: branches/network/src/lib/network/tcp_server_socket.cc
===================================================================
--- branches/network/src/lib/network/tcp_server_socket.cc	(revision 7540)
+++ branches/network/src/lib/network/tcp_server_socket.cc	(revision 7541)
@@ -14,29 +14,124 @@
 */
 
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
 #include "tcp_server_socket.h"
+#include "tcp_socket.h"
 
+
+/* header for debug output */
+#include "debug.h"
+
+TcpServerSocket::TcpServerSocket( int port ) : ServerSocket( port )
+{
+  init();
+  listen(port);
+}
+
+/**
+ * Default destructor
+ */
+TcpServerSocket::~TcpServerSocket( )
+{
+  /* Quit SDL_net */
+  // NOTE: what if other instances of NetworkSocket running?
+  SDLNet_Quit();
+  PRINTF(5)("SDL_net shutdown\n");
+
+  _isListening = false;
+}
+
+void TcpServerSocket::init( )
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_SERVER_SOCKET, "TcpServerSocket");
+
+  terminateThread = false;
+  listenSocket = NULL;
+  _isListening = false;
+
+  if(SDLNet_Init()==-1)
+  {
+    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
+    return;
+  }
+  else
+    PRINTF(5)("SDL_net initialized\n");
+
+  PRINTF(0)("TcpServerSocket created\n");
+}
 
 
 /**
- * constructor which listens on port
- * @param port port
+ * Tells the NetworkSocket to listen on a specific port for incoming connections.
+ * NetworkSocket::writeBytes(...) will have no effect until there is a valuable connection.
+ * @param port
  */
-TcpServerSocket::TcpServerSocket( int port ) : ServerSocket( port )
+bool TcpServerSocket::listen(unsigned int port)
 {
+  PRINTF(0)("TcpServerSocket::listen()\n");
+  _isListening = true;
+  //check if not already connected or listening
+  if (listenSocket)
+  {
+    PRINTF(1)("TcpServerSocket::listen: tcpSocket!=NULL! maybe you already called listen or did not call close()!\n");
+    _isListening = false;
+    return false;
+  }
+
+  IPaddress ip;
+
+  if (SDLNet_ResolveHost(&ip, NULL, port)==-1)
+  {
+    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+    _isListening = false;
+    return false;
+  }
+
+  listenSocket = SDLNet_TCP_Open(&ip);
+
+  if (!listenSocket)
+  {
+    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+    _isListening = false;
+    return false;
+  }
+
+  return true;
 }
 
-TcpServerSocket::~TcpServerSocket( )
+
+NetworkSocket* TcpServerSocket::getNewSocket( )
 {
-}
+  if ( !listenSocket )
+  {
+    PRINTF(1)("listenSocket == NULL! Maybe you forgot to call listen()\n");
+    close();
+    return NULL;
+  }
 
-bool TcpServerSocket::listen( unsigned int port )
-{
-}
+  TCPsocket sock = SDLNet_TCP_Accept(listenSocket);
 
-NetworkSocket * TcpServerSocket::getNewSocket( void )
-{
+  if ( !sock )
+  {
+    return NULL;
+  }
+  else
+  {
+    return new TcpSocket(sock);
+  }
 }
 
 void TcpServerSocket::close( )
 {
+  if ( listenSocket )
+  {
+    SDLNet_TCP_Close( listenSocket );
+    listenSocket = NULL;
+  }
+
+  _isListening = false;
 }
Index: branches/network/src/lib/network/tcp_server_socket.h
===================================================================
--- branches/network/src/lib/network/tcp_server_socket.h	(revision 7540)
+++ branches/network/src/lib/network/tcp_server_socket.h	(revision 7541)
@@ -27,4 +27,12 @@
     virtual NetworkSocket* getNewSocket( void );
     virtual void close();
+    
+  private:
+    TCPsocket listenSocket;
+    bool terminateThread;
+
+    bool _isListening;
+
+    void init();
  
 };
Index: branches/network/src/lib/network/tcp_socket.cc
===================================================================
--- branches/network/src/lib/network/tcp_socket.cc	(revision 7540)
+++ branches/network/src/lib/network/tcp_socket.cc	(revision 7541)
@@ -1,2 +1,3 @@
+
 /*
    orxonox - the future of 3D-vertical-scrollers
@@ -10,65 +11,469 @@
 
 ### File Specific:
-   main-programmer: Christoph Renner
+   main-programmer: Christoph Renner, David Hasenfratz
    co-programmer:
 */
 
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "converter.h"
+
+/* include your own header */
 #include "tcp_socket.h"
 
-/**
- * constructor which connects to host
+/* header for debug output */
+#include "debug.h"
+
+/**
+ * Default constructor
+ */
+TcpSocket::TcpSocket()
+{
+  this->init();
+}
+
+/**
+ * Constructor to connect directly
  */
 TcpSocket::TcpSocket( std::string host, int port )
 {
-} 
-
-/**
- * default constructor
- */
-TcpSocket::TcpSocket( )
-{
-}
-
-/**
- * default destructor
+  this->init();
+  connectToServer( host, port);
+}
+
+
+TcpSocket::TcpSocket( TCPsocket sock )
+{
+  this->init();
+  this->tcpSocket = sock;
+
+  readThread = SDL_CreateThread(thread_read, (void*)this);
+  writeThread = SDL_CreateThread(thread_write, (void*)this);
+}
+
+void TcpSocket::init()
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_NETWORK_SOCKET, "TcpSocket");
+
+  tcpSocket = NULL;
+  incomingBufferLength = 0;
+  outgoingBufferLength = 0;
+
+  readThread = NULL;
+  writeThread = NULL;
+
+
+  thread_write_running = false;
+  thread_read_running = false;
+
+  incomingBufferMutex = SDL_CreateMutex();
+  outgoingBufferMutex = SDL_CreateMutex();
+
+
+  socketMutex = SDL_CreateMutex();
+  terminateThread = false;
+
+  /* Init SDL_net */
+  //NOTE: do we need to call SDLNet_Init for all instances?
+  if(SDLNet_Init()==-1)
+  {
+    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
+    return;
+  }
+  else
+    PRINTF(5)("SDL_net initialized\n");
+
+  PRINTF(0)("TcpSocket created\n");
+
+}
+
+
+
+/**
+ * Default destructor
+ * dont use this from outside: use destroy() instead!!
  */
 TcpSocket::~TcpSocket( )
 {
-}
-    
-/**
- * read a packet sent by another NetworkSocket
- * @param data data will be copied here
- * @param maxLength readPacket will not read more than maxLength
- * @return bytes read. on error less than zero
- */
+  this->terminateThread = true;
+  /* Quit SDL_net */
+  // NOTE: what if other instances of TcpSocket running?
+  SDLNet_Quit();
+  PRINTF(5)("SDL_net shutdown\n");
+
+  SDL_DestroyMutex(incomingBufferMutex);
+  SDL_DestroyMutex(outgoingBufferMutex);
+  SDL_DestroyMutex(socketMutex);
+  SDL_DestroyMutex(threadTerminationMutex);
+}
+
+/**
+ * This function establishes a TCP/UDP connection to a given server (function argument).
+ * It is called by the NetworkStream. It creates a TCP/UDP socket for the connection.
+ * @param ip
+ */
+void TcpSocket::connectToServer( std::string host, int port)
+{
+  IPaddress ip;
+  
+  bOk = true; 
+  
+  if ( SDLNet_ResolveHost( &ip, host.c_str(), port ) != 0 )
+  {
+    PRINTF(1)("could not resolve host %s\n", host.c_str() );
+    bOk = false;
+    return;
+  }
+  
+  //check if not already connected or listening
+  if (tcpSocket)
+  {
+    PRINTF(1)("TcpSocket::listen: tcpSocket!=NULL! maybe you already called listen or connectToServer or did not call disconnectServer()!");
+  }
+
+  /* Connect to the host and port contained in ip using a TCP connection. */
+  tcpSocket = SDLNet_TCP_Open(&ip);
+  if(!tcpSocket)
+  {
+    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+    return;
+  }
+
+  readThread = SDL_CreateThread(thread_read, (void*)this);
+  writeThread = SDL_CreateThread(thread_write, (void*)this);
+}
+
+
+/**
+ * DTears down a TCP/UDP connection.
+ */
+void TcpSocket::disconnectServer( )
+{
+  terminateThread = true;
+  /* Close the connection */
+
+  SDL_mutexP(socketMutex);
+  SDLNet_TCP_Close(tcpSocket);
+  tcpSocket = NULL;
+  SDL_mutexV(socketMutex);
+}
+
+
+/**
+ * This function writes some bytes (data) to the network connection (if the connection is already
+ * estabilhed) otherwise it just does nothing (silently discarding the data). And writes some
+ * warnings
+ * @param data: pointer to the data to send
+ * @param length: n bytes to send
+ * @return the number successfully written bytes
+ */
+int TcpSocket::writeBytes(byte * data, int length)
+{
+  PRINTF(5)("TcpSocket::writeBytes()\n");
+#ifdef _USE_OUTGOING_BUFFER
+
+#define min(a,b) (a<b)?a:b
+  int nbytes = min(_OUTGOING_BUFFER_SIZE - outgoingBufferLength, length);
+#undef min
+
+  if (!tcpSocket || data==NULL || nbytes<=0)
+{
+  assert(_OUTGOING_BUFFER_SIZE - outgoingBufferLength > 0);
+  return 0;
+}
+
+  SDL_mutexP(outgoingBufferMutex);
+
+  memcpy(outgoingBuffer + outgoingBufferLength, data, nbytes);
+  outgoingBufferLength += nbytes;
+
+  SDL_mutexV(outgoingBufferMutex);
+
+
+  return nbytes;
+#else
+  SDL_mutexP(socketMutex);
+
+  if (!tcpSocket || data==NULL)
+    return 0;
+
+  int res = SDLNet_TCP_Send(tcpSocket, data, length);
+
+  SDL_mutexV(socketMutex);
+
+  if (res<length)
+    PRINTF(1)("SDLNet_TCP_Send: %s\n", SDLNet_GetError());
+
+  return res;
+#endif
+}
+
+/**
+ * Reads in the bytes from the network interface and passes it to the NetworkStream.
+ * This function must internaly be implemented/connected as a thread, since the read
+ * functions of many network libraries are blocking an would therefore block the whole
+ * program.
+ * From outside, the thread shouldn't be accessible at all.
+ * @param data: pointer to memory, big enough to store length bytes
+ * @param length: n bytes to read
+ * @return the number successfully read bytes. -1 on error. may be less than length!
+ */
+int TcpSocket::readBytes(byte * data, int length)
+{
+  PRINTF(5)("TcpSocket::readBytes()\n");
+  if (data==NULL)
+    return 0;
+
+  int nbytes = (length<incomingBufferLength) ? length : incomingBufferLength;
+
+
+  //printf("readBytes: nbytes = %d; length=%d; incomingBufferLength=%d\n", nbytes, length, incomingBufferLength);
+
+  // just in case ...
+  if (nbytes<0)
+    return -1;
+
+  if (nbytes==0)
+    return 0;
+
+  SDL_mutexP(incomingBufferMutex);
+
+  memcpy(data, incomingBuffer, nbytes);
+
+  //important: use memmove because the memory areas may overlap
+  memmove(incomingBuffer, incomingBuffer+nbytes, incomingBufferLength-nbytes);
+  incomingBufferLength -= nbytes;
+
+  SDL_mutexV(incomingBufferMutex);
+
+  return nbytes;
+}
+
+/**
+ * Reads in the bytes form the network interface and passes it to the NetworkStream.
+ * It only reads the bytes if there are enough bytes in our buffer.
+ * @param data: pointer to memory, big enough to store length bytes
+ * @param length: n bytes to read
+ * @return the number successfully read bytes. -1 on error. 0 if there are not enough bytes in our buffer.
+ */
+int TcpSocket::readBlock(byte * data, int length)
+{
+  printf("TcpSocket: got %i bytes, NetworkStream requested %i bytes\n", this->incomingBufferLength, length);
+  if (incomingBufferLength >= length)
+    return readBytes(data, length);
+  else return 0;
+}
+
+
+/**
+ * used to create a thread to read from socket
+ * @param data: pointer to TcpSocket
+ */
+int TcpSocket::thread_read( void * data )
+{
+  int nbytesread = 0;
+  int nbytestoread = 0;
+  char buffer[_LOCAL_BUFFER_SIZE];
+  TcpSocket * self = (TcpSocket*)data;
+
+  self->thread_read_running = true;
+
+  while (!self->terminateThread)
+  {
+#define min(a,b) (a<b)?a:b
+    nbytestoread = min(_INCOMING_BUFFER_SIZE - self->incomingBufferLength, _LOCAL_BUFFER_SIZE);
+#undef min
+
+    //if buffer is full
+    if (nbytestoread<=0 || !self->tcpSocket)
+{
+  SDL_Delay(_MSECONDS_SLEEP_FULL_BUFFER);
+  continue;
+}
+
+    nbytesread = SDLNet_TCP_Recv(self->tcpSocket, buffer, nbytestoread);
+
+    SDL_mutexP(self->incomingBufferMutex);
+
+    if (nbytesread<=0)
+{
+  if (nbytesread<0)
+    printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
+
+  SDL_mutexP(self->socketMutex);
+
+  SDLNet_TCP_Close(self->tcpSocket);
+  self->tcpSocket = NULL;
+
+  SDL_mutexV(self->socketMutex);
+  SDL_mutexV(self->incomingBufferMutex);
+  continue;
+}
+
+    //printf("thread_read: nbytesread=%d\n", nbytesread);
+
+    memcpy(self->incomingBuffer+self->incomingBufferLength, buffer, nbytesread);
+    self->incomingBufferLength += nbytesread;
+
+    SDL_mutexV(self->incomingBufferMutex);
+  }
+
+  SDL_mutexP(self->threadTerminationMutex);
+  self->thread_read_running = false;
+
+  if ( !self->thread_write_running )
+{
+    //delete self;
+  SDL_mutexV(self->threadTerminationMutex);
+}
+  else
+{
+  SDL_mutexV(self->threadTerminationMutex);
+}
+
+
+#ifdef DONTEXITTHREADS
+  while ( true )
+{
+  SDL_Delay(1000);
+}
+#endif
+  
+  PRINTF(0)("QUIT READ THREAD\n");
+  
+  return 0;
+}
+
+int TcpSocket::thread_write( void * data )
+{
+  int nbyteswrite = 0;
+  int nbytestowrite = 0;
+  char buffer[_LOCAL_BUFFER_SIZE];
+  TcpSocket * self = (TcpSocket*)data;
+
+  self->thread_write_running = true;
+
+  while (!self->terminateThread)
+  {
+#define min(a,b) (a<b)?a:b
+    nbytestowrite = min(self->outgoingBufferLength, _LOCAL_BUFFER_SIZE);
+#undef min
+
+//     printf("thread_write nbytes=%d listening=%d\n", nbytestowrite, (int)self->_isListening);
+
+    //if buffer is full
+    if (nbytestowrite<=0 || !self->tcpSocket)
+{
+  SDL_Delay(_MSECONDS_SLEEP_EMPTY_BUFFER);
+  continue;
+}
+
+    SDL_mutexP(self->outgoingBufferMutex);
+
+    //printf("a\n");
+
+    memcpy(buffer, self->outgoingBuffer, nbytestowrite);
+    self->outgoingBufferLength -= nbytestowrite;
+    memmove(self->outgoingBuffer, self->outgoingBuffer+nbytestowrite, self->outgoingBufferLength);
+
+    SDL_mutexV(self->outgoingBufferMutex);
+
+    nbyteswrite = SDLNet_TCP_Send(self->tcpSocket, buffer, nbytestowrite);
+
+    if (nbyteswrite<=0)
+{
+  printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
+
+  SDL_mutexP(self->socketMutex);
+
+  SDLNet_TCP_Close(self->tcpSocket);
+  self->tcpSocket = NULL;
+
+  SDL_mutexV(self->socketMutex);
+  continue;
+}
+
+  }
+
+  SDL_mutexP(self->threadTerminationMutex);
+  self->thread_write_running = false;
+
+  if ( !self->thread_read_running )
+{
+    //delete self;
+  SDL_mutexV(self->threadTerminationMutex);
+}
+  else
+{
+  SDL_mutexV(self->threadTerminationMutex);
+}
+
+#ifdef DONTEXITTHREADS
+  while ( true )
+{
+  SDL_Delay(1000);
+}
+#endif
+
+  PRINTF(0)("QUIT WRITE THREAD\n");
+
+  return 0;
+  
+}
+
+bool TcpSocket::writePacket( byte * data, int length )
+{
+  PRINTF(5)("TcpSocket::writePacket() size=%d\n", length);
+
+  if ( length > 1024 )
+    PRINTF(2)("WARNING SENDING BIG PACKET SIZE = %d\n", length);
+
+  byte blen[INTSIZE];
+
+  Converter::intToByteArray( length, blen, INTSIZE );
+
+  writeBytes(blen, INTSIZE);
+  writeBytes(data, length);
+}
+
 int TcpSocket::readPacket( byte * data, int maxLength )
 {
-}
-
-/**
- * send packet to connected socket. will be recieved as whole packet
- * @param data pointer to data to send
- * @param length lengt of packet to send
- * @return true on success
- */
-bool TcpSocket::writePacket( byte * data, int length )
-{
-}
-
-/**
- * disconnect from server
- */
-void TcpSocket::disconnectServer( )
-{
-}
-
-/**
- * connect to server on host with port port
- * @param host hostname might be xxx.xxx.xxx.xxx or localhost ...
- * @param port port to connect to
- */
-void TcpSocket::connectToServer( std::string host, int port )
-{
-}
-
+  PRINTF(5)("TcpSocket::readPacket()\n");
+  if (incomingBufferLength<INTSIZE)
+  {
+    return 0;
+  }
+
+  int blen;
+  Converter::byteArrayToInt( incomingBuffer, &blen );
+
+  if (blen>maxLength)
+  {
+    PRINTF(1)("Buffersize is too small (%d) for packet (%d).\n", maxLength, blen);
+    assert(false);
+    return 0;
+  }
+
+  if (blen>incomingBufferLength)
+  {
+    return 0;
+  }
+
+  byte t[INTSIZE];
+  readBytes(t, INTSIZE);
+  int res = readBytes(data, blen);
+
+  if (res!=blen)
+    return -1;
+  else
+    return blen;
+
+}
+
+
Index: branches/network/src/lib/network/tcp_socket.h
===================================================================
--- branches/network/src/lib/network/tcp_socket.h	(revision 7540)
+++ branches/network/src/lib/network/tcp_socket.h	(revision 7541)
@@ -8,9 +8,32 @@
 #define _TCP_SOCKET
 
+//TODO HACK else gdb will not work on server
+#define DONTEXITTHREADS
+
+//if you want to use outgoing buffer define _USE_OUTGOING_BUFFER
+#define _USE_OUTGOING_BUFFER
+
+#define _INCOMING_BUFFER_SIZE 2024000
+#define _OUTGOING_BUFFER_SIZE 2024000
+#define _LOCAL_BUFFER_SIZE 1024
+//sleep if incoming buffer is full
+#define _MSECONDS_SLEEP_FULL_BUFFER 10
+//sleep if outgoing buffer is empty
+#define _MSECONDS_SLEEP_EMPTY_BUFFER 10
+
+
+/* contains memmove and memcpy */
+#include <string.h>
+
+#ifdef HAVE_SDL_H
+#include <SDL_thread.h>
+#else
+#include <SDL/SDL_thread.h>
+#endif
 /* include this file, it contains some default definitions */
 #include "netdefs.h"
 
 
-/* include base_object.h since all classes are derived from this one */
+/* include network_socket.h since all classes are derived from this one */
 #include "network_socket.h"
 
@@ -20,4 +43,5 @@
     TcpSocket();
     TcpSocket( std::string host, int port );
+    TcpSocket(TCPsocket sock);
     virtual ~TcpSocket();
 
@@ -30,4 +54,40 @@
     virtual int readPacket(byte * data, int maxLength);
 
+  private:
+    TCPsocket tcpSocket;
+
+    byte incomingBuffer[_INCOMING_BUFFER_SIZE];
+#ifdef _USE_OUTGOING_BUFFER
+  byte outgoingBuffer[_OUTGOING_BUFFER_SIZE];
+#endif
+  int incomingBufferLength;
+#ifdef _USE_OUTGOING_BUFFER
+  int outgoingBufferLength;
+#endif
+
+  SDL_mutex * incomingBufferMutex;
+#ifdef _USE_OUTGOING_BUFFER
+  SDL_mutex * outgoingBufferMutex;
+#endif
+  SDL_mutex * socketMutex;
+  bool terminateThread;
+
+  SDL_mutex* threadTerminationMutex;
+  static int thread_read(void * data);
+  bool thread_read_running;
+  bool thread_write_running;
+
+  SDL_Thread*            readThread;
+  SDL_Thread*            writeThread;
+
+#ifdef _USE_OUTGOING_BUFFER
+  static int thread_write(void * data);
+#endif
+
+  int writeBytes(byte * data, int length);
+  int readBytes(byte * data, int length);
+  int readBlock(byte * data, int length);
+
+  void init();
 
 };
Index: branches/network/src/lib/network/udp_socket.cc
===================================================================
--- branches/network/src/lib/network/udp_socket.cc	(revision 7540)
+++ branches/network/src/lib/network/udp_socket.cc	(revision 7541)
@@ -20,4 +20,5 @@
 void UdpSocket::init( )
 {
+  //TODO setClassId
   this->serverSocket = NULL;
   this->socket = NULL;
