Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

netclient.cpp

Go to the documentation of this file.
00001 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
00002 
00003    this file is part of rcssserver3D
00004    Fri May 9 2003
00005    Copyright (C) 2002,2003 Koblenz University
00006    Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group
00007    $Id: netclient.cpp,v 1.3 2005/12/08 10:26:19 jamu Exp $
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; version 2 of the License.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 #include "netclient.h"
00023 #include <zeitgeist/logserver/logserver.h>
00024 #include <netinet/in.h>
00025 #include <rcssnet/exception.hpp>
00026 #include <cerrno>
00027 
00028 using namespace oxygen;
00029 using namespace zeitgeist;
00030 using namespace rcss::net;
00031 using namespace salt;
00032 using namespace boost;
00033 using namespace std;
00034 
00035 NetClient::NetClient() : SimControlNode()
00036 {
00037     mHost = "127.0.0.1";
00038     mPort = 3200;
00039     mBufferSize = 64 * 1024;
00040     mBuffer = shared_array<char>(new char[mBufferSize]);
00041     mType = NetControl::ST_TCP;
00042     mNetBuffer = shared_ptr<NetBuffer>(new NetBuffer());
00043 }
00044 
00045 NetClient::~NetClient()
00046 {
00047 }
00048 
00049 void NetClient::SetServer(const std::string& host)
00050 {
00051     mHost = host;
00052 }
00053 
00054 const std::string& NetClient::GetServer() const
00055 {
00056     return mHost;
00057 }
00058 
00059 void NetClient::SetPort(int port)
00060 {
00061     mPort = port;
00062 }
00063 
00064 int NetClient::GetPort() const
00065 {
00066     return mPort;
00067 }
00068 
00069 void NetClient::SetClientType(NetControl::ESocketType type)
00070 {
00071     mType = type;
00072 }
00073 
00074 NetControl::ESocketType NetClient::GetClientType()
00075 {
00076     return mType;
00077 }
00078 
00079 bool NetClient::Connect()
00080 {
00081     mSocket = NetControl::CreateSocket(mType);
00082 
00083     if (mSocket.get() == 0)
00084         {
00085             return false;
00086         }
00087 
00088     GetLog()->Normal()
00089         << "(NetClient) '" << GetName() << "'connecting to "
00090         << ((mType == NetControl::ST_UDP) ? "UDP " : "TCP ")
00091         << mHost << ":" << mPort << "\n";
00092 
00093     try
00094         {
00095             Addr local(INADDR_ANY,INADDR_ANY);
00096             mSocket->bind(local);
00097         }
00098 
00099     catch (BindErr error)
00100         {
00101             GetLog()->Error()
00102                 << "(NetClient) '" << GetName()
00103                 << "' failed to bind socket with '"
00104                 << error.what() << "'" << endl;
00105 
00106             mSocket->close();
00107             return false;
00108         }
00109 
00110     try
00111         {
00112             Addr server(mPort,mHost);
00113             mSocket->connect(server);
00114         }
00115 
00116     catch (ConnectErr error)
00117         {
00118             GetLog()->Error()
00119                 << "(NetClient) '" << GetName()
00120                 << "' connection failed with: '"
00121                 << error.what() << "'" << endl;
00122             mSocket->close();
00123             mSocket.reset();
00124             return false;
00125         }
00126 
00127     if (mSocket->isConnected())
00128         {
00129             cout << "(NetClient) '" << GetName()
00130                  << "' connected successfully" << endl;
00131         }
00132 
00133   // assure that a NetMessage object is registered
00134   mNetMessage = FindChildSupportingClass<NetMessage>();
00135 
00136   if (mNetMessage.get() == 0)
00137       {
00138           mNetMessage = shared_ptr<NetMessage>(new NetMessage());
00139       }
00140 
00141   return true;
00142 }
00143 
00144 void NetClient::SendMessage(const string& msg)
00145 {
00146     if (mNetMessage.get() == 0)
00147         {
00148             return;
00149         }
00150 
00151     string preparedMsg = msg;
00152     mNetMessage->PrepareToSend(preparedMsg);;
00153 
00154     if (mSocket.get() == 0)
00155         {
00156             return;
00157         }
00158 
00159     int rval = 0;
00160 
00161     if (mType == NetControl::ST_UDP)
00162         {
00163             Addr server(mPort,mHost);
00164             rval = mSocket->send(msg.data(), msg.size(), server);
00165         } else
00166             {
00167                 rval = mSocket->send(preparedMsg.data(), preparedMsg.size());
00168             }
00169 
00170     if (rval < 0)
00171         {
00172             GetLog()->Error()
00173                 << "(NetClient::SendMessage) ERROR: "
00174                 << "send returned error '"
00175                 << strerror(errno) << "' " << endl;
00176         }
00177 }
00178 
00179 void NetClient::CloseConnection()
00180 {
00181     if (mSocket.get() == 0)
00182         {
00183             return;
00184         }
00185 
00186     mSocket->close();
00187     mSocket.reset();
00188 
00189     GetLog()->Normal() << "(NetClient) '" << GetName()
00190                        << "' closed connection to "
00191                        << mHost << ":" << mPort << "\n";
00192 
00193     mNetMessage.reset();
00194 }
00195 
00196 void NetClient::ReadFragments()
00197 {
00198     if (mSocket.get() == 0)
00199         {
00200             return;
00201         }
00202 
00203     for (;;)
00204         {
00205             // test for available data
00206             int fd = mSocket->getFD();
00207 
00208             fd_set readfds;
00209             FD_ZERO(&readfds);
00210             FD_SET(fd,&readfds);
00211 
00212             timeval time;
00213             time.tv_sec = 0;
00214             time.tv_usec = 0;
00215 
00216             int rval = select(fd+1, &readfds, 0, 0, &time );
00217 
00218             if (rval == 0)
00219                 {
00220                     break;
00221                 }
00222 
00223             if (rval < 0)
00224                 {
00225                     GetLog()->Error()
00226                         << "(NetClient) ERROR select on client "
00227                         << "socket failed with '"
00228                         << strerror(errno) << "'" << endl;
00229                     CloseConnection();
00230                     return;
00231                 }
00232 
00233             rval = mSocket->recv(mBuffer.get(),mBufferSize);
00234 
00235             if (rval == 0)
00236                 {
00237                     CloseConnection();
00238                     return;
00239                 }
00240 
00241             if (rval < 0)
00242                 {
00243                     GetLog()->Error()
00244                         << "(NetClient) '" << GetName()
00245                         << "' ERROR: '" << GetName()
00246                         << "' recv returned error '"
00247                         << strerror(errno) << "' " << endl;
00248                     return;
00249                 }
00250 
00251             string fragment(mBuffer.get(),rval);
00252             mNetBuffer->AddFragment(string(mBuffer.get(),rval));
00253         }
00254 }

Generated on Thu Apr 6 15:25:39 2006 for rcssserver3d by  doxygen 1.4.4