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

ArNetPacketSenderTcp.cpp

Go to the documentation of this file.
00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArNetPacketSenderTcp.h"
00029 
00030 AREXPORT ArNetPacketSenderTcp::ArNetPacketSenderTcp() :
00031   mySocket(NULL),
00032   myPacketList(),
00033   myPacket(NULL),
00034   myAlreadySent(false),
00035   myBuf(NULL),
00036   myLength(0)
00037 {
00038 }
00039 
00040 AREXPORT ArNetPacketSenderTcp::~ArNetPacketSenderTcp()
00041 {
00042   ArNetPacket *packet;
00043   while (myPacketList.begin() != myPacketList.end())
00044   {
00045     packet = myPacketList.front();
00046     myPacketList.pop_front();
00047     delete packet;
00048   }
00049 }
00050 
00057 AREXPORT void ArNetPacketSenderTcp::setSocket(ArSocket *socket)
00058 {
00059   myDataMutex.lock();
00060   mySocket = socket;
00061   myDataMutex.unlock();
00062 }
00063 
00068 AREXPORT ArSocket *ArNetPacketSenderTcp::getSocket(void)
00069 {
00070   return mySocket;
00071 }
00072 
00073 AREXPORT void ArNetPacketSenderTcp::sendPacket(ArNetPacket *packet)
00074 {
00075   ArNetPacket *sendPacket;
00076   sendPacket = new ArNetPacket(packet->getLength() + 5);
00077   sendPacket->duplicatePacket(packet);
00078   myDataMutex.lock();
00079   myPacketList.push_back(sendPacket);
00080   myDataMutex.unlock();
00081 }
00082 
00083 AREXPORT bool ArNetPacketSenderTcp::sendData(void)
00084 {
00085   int ret;
00086   ArTime start;
00087   start.setToNow();
00088   //printf("sendData %g\n", start.mSecSince() / 1000.0);
00089   myDataMutex.lock();
00090   while (myPacketList.begin() != myPacketList.end() || myPacket != NULL)
00091   {
00092     if (myPacket == NULL)
00093     {
00094       //printf("!startedSending %g\n", start.mSecSince() / 1000.0);
00095       myPacket = myPacketList.front();
00096       myPacketList.pop_front();
00097       myAlreadySent = 0;
00098       myBuf = myPacket->getBuf();
00099       myLength = myPacket->getLength();
00100 
00101       if (myPacket->getCommand() == 0 || myPacket->getCommand() > 1000)
00102       {
00103         ArLog::log(ArLog::Normal, "getCommand is %d when it probably shouldn't be", 
00104                    myPacket->getCommand());
00105       }
00106     }
00107     if (myLength < 0 || myLength > ArNetPacket::MAX_LENGTH)
00108     {
00109       ArLog::log(ArLog::Terse, "ArNetPacketSenderTcp: getLength for command %d packet is bad at %d", myPacket->getCommand(), myLength);
00110       delete myPacket;
00111       myPacket = NULL;
00112       continue;
00113     }
00114     ret = mySocket->write(&myBuf[myAlreadySent], myLength - myAlreadySent);
00115     if (ret < 0)
00116     {
00117 #ifdef WIN32
00118       if (WSAGetLastError() == WSAEWOULDBLOCK)
00119       {
00120         myDataMutex.unlock();
00121         return true;
00122       }
00123       else 
00124       {
00125         ArLog::log(ArLog::Normal, "ArNetPacketSenderTcp: Windows failed write with error %d on packet %d with length of %d", WSAGetLastError(), myPacket->getCommand(), myLength);
00126         myDataMutex.unlock();
00127         return false;
00128       }
00129 
00130 #else
00131       if (errno == EAGAIN)/* || errno == EINTR)*/
00132       {
00133         myDataMutex.unlock();
00134         return true;
00135       }
00136       else 
00137       {
00138         ArLog::log(ArLog::Normal, "ArNetPacketSenderTcp: Linux failed write with error %d on packet %d with length of %d", errno, myPacket->getCommand(), myLength);
00139         myDataMutex.unlock();
00140         return false;
00141       }
00142 #endif 
00143     }
00144     else if (ret == 0)
00145     {
00146       // If network connectivity goes down for a length of time, and the
00147       // socket's buffer fills, we will have this error. An alternative action
00148       // would be to  retain myAlreadySent at its current value and keep trying to 
00149       // write data to the socket, in the hope that the network will come back.
00150       ArLog::log(ArLog::Verbose, "ArNetPacketSenderTcp: Couldn't send packet with command %d and length %d: No data could be sent through socket (%d bytes sent until now).", myPacket->getCommand(), myLength, myAlreadySent);
00151       myDataMutex.unlock();
00152       return true;
00153     }
00154     else if (ret > 0)
00155     {
00156       myAlreadySent += ret;
00157       if (myAlreadySent == myLength)
00158       {
00159         //printf("sent one %g\n", start.mSecSince() / 1000.0);
00160         delete myPacket;
00161         myPacket = NULL;
00162         continue;
00163       }
00164     }
00165     else
00166     {
00167       ArLog::log(ArLog::Terse, "ArNetPacketSenderTcp: Bad case in sendData");
00168       
00169     }
00170   }
00171   myDataMutex.unlock();
00172   return true;
00173 }

Generated on Tue Feb 20 10:51:50 2007 for ArNetworking by  doxygen 1.4.0