00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
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 }