00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "netcontrol.h"
00021 #include "netmessage.h"
00022 #include <zeitgeist/logserver/logserver.h>
00023 #include <netinet/in.h>
00024 #include <rcssnet/exception.hpp>
00025 #include <rcssnet/tcpsocket.hpp>
00026 #include <rcssnet/udpsocket.hpp>
00027 #include <sstream>
00028 #include <cerrno>
00029
00030 using namespace rcss::net;
00031 using namespace oxygen;
00032 using namespace zeitgeist;
00033 using namespace boost;
00034 using namespace std;
00035
00036 NetControl::NetControl() : SimControlNode()
00037 {
00038 mBufferSize = 64 * 1024;
00039 mBuffer = shared_array<char>(new char[mBufferSize]);
00040 mSocketType = ST_TCP;
00041 mLocalAddr = Addr(INADDR_ANY, INADDR_ANY);
00042 mClientId = 1;
00043 }
00044
00045 NetControl::~NetControl()
00046 {
00047 }
00048
00049 void NetControl::SetServerPort(Addr::PortType port)
00050 {
00051 mLocalAddr.setPort(port);
00052 }
00053
00054 rcss::net::Addr::PortType NetControl::GetServerPort()
00055 {
00056 return mLocalAddr.getPort();
00057 }
00058
00059 void NetControl::SetServerType(ESocketType type)
00060 {
00061 mSocketType = type;
00062 }
00063
00064 NetControl::ESocketType NetControl::GetServerType()
00065 {
00066 return mSocketType;
00067 }
00068
00069 boost::shared_ptr<Socket> NetControl::CreateSocket(ESocketType type)
00070 {
00071 shared_ptr<Socket> socket;
00072
00073 try
00074 {
00075 switch (type)
00076 {
00077 case ST_UDP:
00078 socket = shared_ptr<Socket>(new UDPSocket());
00079 break;
00080
00081 case ST_TCP:
00082 socket = shared_ptr<Socket>(new TCPSocket());
00083 break;
00084
00085 default:
00086 cerr << "(NetControl) ERROR: unknown socket type "
00087 << type << "\n";
00088 break;
00089 }
00090 }
00091
00092 catch (OpenErr error)
00093 {
00094 cerr << "(NetControl) failed to create socket with '"
00095 << error.what()
00096 << endl;
00097 }
00098
00099 return socket;
00100 }
00101
00102 string NetControl::DescribeSocketType()
00103 {
00104 stringstream ss;
00105
00106 switch (mSocketType)
00107 {
00108 case ST_UDP:
00109 ss << "UDP";
00110 break;
00111
00112 case ST_TCP:
00113 ss << "TCP";
00114 break;
00115
00116 default:
00117 ss << "(unknown socket type)";
00118 break;
00119 }
00120
00121 ss << ":" << mLocalAddr.getPort();
00122
00123 return ss.str();
00124 }
00125
00126 void NetControl::InitSimulation()
00127 {
00128
00129 if (mLocalAddr.getPort() == INADDR_ANY)
00130 {
00131 GetLog()->Error()
00132 << "(NetControl) ERROR: local port has no been set in '"
00133 << GetClass()->GetName() << "'\n";
00134 return;
00135 }
00136
00137 GetLog()->Normal() << "(NetControl) '" << GetName()
00138 << "' setting up a server on " << DescribeSocketType() << std::endl;
00139
00140 mSocket = CreateSocket(mSocketType);
00141
00142 if (mSocket.get() == 0)
00143 {
00144 return;
00145 }
00146
00147 int ret = mSocket->setNonBlocking(true);
00148
00149 if (ret < 0)
00150 {
00151 GetLog()->Error()
00152 << "(NetControl) failed to set server socket to non "
00153 << "blocking mode with '"
00154 << strerror(errno) << "'\n";
00155 mSocket->close();
00156 return;
00157 }
00158
00159 try
00160 {
00161 mSocket->bind(mLocalAddr);
00162 }
00163
00164 catch (BindErr error)
00165 {
00166 GetLog()->Error() << "(NetControl) failed to bind socket with '"
00167 << error.what() << "'"
00168 << endl;
00169
00170 mSocket->close();
00171 return;
00172 }
00173
00174 try
00175 {
00176 if (mSocketType == ST_TCP)
00177 {
00178 #ifdef SOMAXCONN
00179 mSocket->listen(SOMAXCONN);
00180 #else
00181 mSocket->listen(50);
00182 #endif
00183 }
00184 }
00185
00186 catch (ListenErr error)
00187 {
00188 GetLog()->Error() << "(NetControl) failed to listen on socket with '"
00189 << error.what() << "'"
00190 << endl;
00191
00192 mSocket->close();
00193 return;
00194 }
00195
00196
00197 mNetMessage = FindChildSupportingClass<NetMessage>();
00198
00199 if (mNetMessage.get() == 0)
00200 {
00201 mNetMessage = shared_ptr<NetMessage>(new NetMessage());
00202 }
00203 }
00204
00205 void NetControl::DoneSimulation()
00206 {
00207
00208 mNetMessage.reset();
00209
00210
00211 for (
00212 TAddrMap::iterator iter = mClients.begin();
00213 iter != mClients.end();
00214 ++iter
00215 )
00216 {
00217 RemoveClient((*iter).second->addr);
00218 }
00219
00220
00221 mSocket->close();
00222 GetLog()->Normal() << "(NetControl) '" << GetName()
00223 << "' closed server socket "
00224 << DescribeSocketType() << std::endl;
00225 mSocket.reset();
00226
00227 mClients.clear();
00228 }
00229
00230 void NetControl::AddClient(const Addr& from, shared_ptr<Socket> socket)
00231 {
00232 shared_ptr<Client> client(new Client(mClientId,from,socket));
00233 mClients[from] = client;
00234
00235 GetLog()->Normal()
00236 << "(NetControl) '" << GetName() << "' accepted a "
00237 << ((socket.get() != 0) ? "TCP" : "UDP")
00238 << " connection from '"
00239 << from.getHostStr() << ":" << from.getPort()
00240 << "' id " << mClientId
00241 << endl;
00242
00243 mClientId++;
00244 ClientConnect(client);
00245 }
00246
00247 void NetControl::RemoveClient(const Addr& from)
00248 {
00249 TAddrMap::iterator mapIter = mClients.find(from);
00250
00251 if (mapIter == mClients.end())
00252 {
00253 GetLog()->Warning()
00254 << "(NetControl) '" << GetName()
00255 << "' RemoveClient called with an unknown client address\n";
00256 return;
00257 }
00258
00259 shared_ptr<Client> client = (*mapIter).second;
00260 ClientDisconnect(client);
00261
00262 shared_ptr<Socket> socket = client->socket;
00263
00264 GetLog()->Normal()
00265 << "(NetControl) '" << GetName() << "' closing a "
00266 << ((socket.get() != 0) ? "TCP" : "UDP")
00267 << " connection from '"
00268 << from.getHostStr() << ":" << from.getPort()
00269 << "' id " << client->id << endl;
00270
00271 if (socket.get() != 0)
00272 {
00273 socket->close();
00274 }
00275
00276 mClients.erase(mapIter);
00277 }
00278
00279 void NetControl::ClientConnect(shared_ptr<Client> )
00280 {
00281
00282 }
00283
00284 void NetControl::ClientDisconnect(shared_ptr<Client> )
00285 {
00286
00287 }
00288
00289 void NetControl::SendMessage(shared_ptr<Client> client, const string& msg)
00290 {
00291 if (client.get() == 0)
00292 {
00293 return;
00294 }
00295
00296 int rval = 0;
00297 shared_ptr<Socket> socket = client->socket;
00298
00299 if (socket.get() == 0)
00300 {
00301
00302 if (mSocket.get() != 0)
00303 {
00304 rval = mSocket->send(msg.data(), msg.size(), client->addr);
00305 }
00306 } else
00307 {
00308
00309 rval = socket->send(msg.data(), msg.size());
00310 }
00311
00312 if (rval < 0)
00313 {
00314 GetLog()->Error()
00315 << "(NetControl::SendMessage) ERROR: '" << GetName()
00316 << "' send returned error '"
00317 << strerror(errno) << "' " << endl;
00318 }
00319 }
00320
00321 void NetControl::SendMessage(const Addr& addr, const string& msg)
00322 {
00323 TAddrMap::iterator iter = mClients.find(addr);
00324
00325 if (iter == mClients.end())
00326 {
00327 GetLog()->Error()
00328 << "(NetControl::SendMessage) ERROR: unknown client address '"
00329 << addr.getHostStr() << ":" << addr.getPort() << "'\n";
00330 return;
00331 }
00332
00333 SendMessage((*iter).second,msg);
00334 }
00335
00336 void NetControl::AcceptTCPConnections()
00337 {
00338 if (
00339 (mSocketType != ST_TCP) ||
00340 (mSocket.get() == 0)
00341 )
00342 {
00343 return;
00344 }
00345
00346 int fd = mSocket->getFD();
00347
00348 fd_set readfds;
00349 FD_ZERO(&readfds);
00350 FD_SET(fd,&readfds);
00351
00352 timeval time;
00353 time.tv_sec = 0;
00354 time.tv_usec = 0;
00355
00356 for(;;)
00357 {
00358 int ret = select(fd+1, &readfds, 0, 0, &time);
00359
00360 if (ret == 0)
00361 {
00362
00363 break;
00364 }
00365
00366 if (ret < 0)
00367 {
00368 GetLog()->Error()
00369 << "(NetControl) ERROR: '" << GetName()
00370 << "' select returned error on server socket "
00371 << DescribeSocketType()
00372 << ' ' << strerror(errno) << "\n"
00373 << "(NetControl) ERROR: closing server socket"
00374 << endl;
00375
00376 mSocket->close();
00377 mSocket.reset();
00378 break;
00379 }
00380
00381 try
00382 {
00383 Addr addr;
00384 shared_ptr<Socket> socket(mSocket->accept(addr));
00385
00386 int ret = socket->setNonBlocking(true);
00387
00388 if (ret < 0)
00389 {
00390 GetLog()->Error()
00391 << "(NetControl) failed to set client socket to"
00392 << " non blocking mode with '"
00393 << strerror(errno)
00394 << "'. closing connection\n";
00395
00396 socket->close();
00397 } else
00398 {
00399 AddClient(addr,socket);
00400 }
00401 }
00402
00403 catch (AcceptErr error)
00404 {
00405 GetLog()->Error()
00406 << "(NetControl) '" << GetName()
00407 << "' failed to accept TCP connection with '"
00408 << error.what() << endl;
00409 break;
00410 }
00411 }
00412 }
00413
00414 void NetControl::CloseDeadConnections()
00415 {
00416 while (! mCloseClients.empty())
00417 {
00418 RemoveClient(mCloseClients.front());
00419 mCloseClients.pop_front();
00420 }
00421 }
00422
00423 void NetControl::StartCycle()
00424 {
00425
00426
00427 ReadMessages();
00428
00429
00430 AcceptTCPConnections();
00431 }
00432
00433 void NetControl::EndCycle()
00434 {
00435
00436 CloseDeadConnections();
00437 }
00438
00439 void NetControl::ReadMessages()
00440 {
00441 switch (mSocketType)
00442 {
00443 case ST_TCP:
00444 ReadTCPMessages();
00445 break;
00446
00447 case ST_UDP:
00448 ReadUDPMessages();
00449 break;
00450
00451 default:
00452 break;
00453 }
00454 }
00455
00456 void NetControl::StoreFragment(const Addr& addr, int size)
00457 {
00458 TBufferMap::iterator msgIter = mBuffers.find(addr);
00459 if (msgIter == mBuffers.end())
00460 {
00461
00462 mBuffers[addr] =
00463 (shared_ptr<NetBuffer>
00464 (new NetBuffer(addr,string(mBuffer.get(),size)))
00465 );
00466 } else
00467 {
00468
00469 (*msgIter).second->AddFragment(string(mBuffer.get(),size));
00470 }
00471 }
00472
00473 void NetControl::ReadUDPMessages()
00474 {
00475 if (mSocket.get() == 0)
00476 {
00477 return;
00478 }
00479
00480 int fd = mSocket->getFD();
00481
00482 fd_set readfds;
00483 FD_ZERO(&readfds);
00484 FD_SET(fd,&readfds);
00485
00486 timeval time;
00487 time.tv_sec = 0;
00488 time.tv_usec = 0;
00489
00490 for(;;)
00491 {
00492 int ret = select(fd+1, &readfds, 0, 0, &time);
00493
00494 if (ret == 0)
00495 {
00496
00497 break;
00498 }
00499
00500 if (ret < 0)
00501 {
00502 GetLog()->Error()
00503 << "(NetControl) ERROR: ReadUDPSocket '" << GetName()
00504 << "' select returned error on server socket "
00505 << DescribeSocketType()
00506 << ' ' << strerror(errno) << endl;
00507 break;
00508 }
00509
00510
00511 Addr from;
00512 int rval = mSocket->recv(mBuffer.get(), mBufferSize, from);
00513
00514 if (rval < 0)
00515 {
00516 GetLog()->Error()
00517 << "(NetControl) ERROR: ReadUDPSocket '" << GetName()
00518 << "' recv returned error '"
00519 << strerror(errno) << "' " << endl;
00520 continue;
00521 }
00522
00523 TAddrMap::iterator iter = mClients.find(from);
00524 if (iter == mClients.end())
00525 {
00526
00527 AddClient(from);
00528 }
00529
00530 StoreFragment(from,rval);
00531 }
00532 }
00533
00534 void NetControl::ReadTCPMessages()
00535 {
00536
00537 fd_set client_fds;
00538 FD_ZERO(&client_fds);
00539
00540 int maxFd = 0;
00541
00542 for (
00543 TAddrMap::iterator iter=mClients.begin();
00544 iter != mClients.end();
00545 ++iter
00546 )
00547 {
00548 const int fd = (*iter).second->socket->getFD();
00549 maxFd = std::max<int>(fd,maxFd);
00550 FD_SET(fd,&client_fds);
00551 }
00552
00553
00554 for(;;)
00555 {
00556 timeval time;
00557 time.tv_sec = 0;
00558 time.tv_usec = 0;
00559
00560 fd_set test_fds = client_fds;
00561 int ret = select(maxFd+1, &test_fds, 0, 0, &time);
00562
00563 if (ret == 0)
00564 {
00565
00566 break;
00567 }
00568
00569 if (ret < 0)
00570 {
00571 GetLog()->Error()
00572 << "(NetControl) ERROR: '" << GetName()
00573 << "' select returned error on client sockets '"
00574 << strerror(errno) << "' " << endl;
00575
00576 break;
00577 }
00578
00579
00580 for (
00581 TAddrMap::iterator iter=mClients.begin();
00582 iter != mClients.end();
00583 ++iter
00584 )
00585 {
00586 const int fd = (*iter).second->socket->getFD();
00587 if (! FD_ISSET(fd, &test_fds))
00588 {
00589 continue;
00590 }
00591
00592
00593 shared_ptr<Client>& client = (*iter).second;
00594 int rval = client->socket->recv(mBuffer.get(),mBufferSize);
00595
00596 if (rval > 0)
00597 {
00598 StoreFragment(client->addr,rval);
00599 } else
00600 {
00601 if (rval < 0)
00602 {
00603 GetLog()->Error()
00604 << "(NetControl) ERROR: '" << GetName()
00605 << "' recv returned error on a client socket '"
00606 << strerror(errno) << "' " << endl;
00607 continue;
00608 }
00609
00610
00611
00612
00613
00614
00615
00616 FD_CLR(fd,&client_fds);
00617 mCloseClients.push_back(client->addr);
00618 }
00619 }
00620 }
00621 }
00622