📄 netcontrol.cpp
字号:
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2003 Koblenz University $Id: netcontrol.cpp,v 1.5 2004/12/21 23:04:46 tomhoward Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "netcontrol.h"#include "netmessage.h"#include <zeitgeist/logserver/logserver.h>#include <netinet/in.h>#include <rcssnet/exception.hpp>#include <rcssnet/tcpsocket.hpp>#include <rcssnet/udpsocket.hpp>#include <sstream>#include <cerrno>using namespace rcss::net;using namespace oxygen;using namespace zeitgeist;using namespace boost;using namespace std;NetControl::NetControl() : SimControlNode(){ mBufferSize = 64 * 1024; mBuffer = shared_array<char>(new char[mBufferSize]); mSocketType = ST_TCP; mLocalAddr = Addr(INADDR_ANY, INADDR_ANY); mClientId = 1;}NetControl::~NetControl(){}void NetControl::SetServerPort(Addr::PortType port){ mLocalAddr.setPort(port);}rcss::net::Addr::PortType NetControl::GetServerPort(){ return mLocalAddr.getPort();}void NetControl::SetServerType(ESocketType type){ mSocketType = type;}NetControl::ESocketType NetControl::GetServerType(){ return mSocketType;}boost::shared_ptr<Socket> NetControl::CreateSocket(ESocketType type){ shared_ptr<Socket> socket; try { switch (type) { case ST_UDP: socket = shared_ptr<Socket>(new UDPSocket()); break; case ST_TCP: socket = shared_ptr<Socket>(new TCPSocket()); break; default: cerr << "(NetControl) ERROR: unknown socket type " << type << "\n"; break; } } catch (OpenErr error) { cerr << "(NetControl) failed to create socket with '" << error.what() << endl; } return socket;}string NetControl::DescribeSocketType(){ stringstream ss; switch (mSocketType) { case ST_UDP: ss << "UDP"; break; case ST_TCP: ss << "TCP"; break; default: ss << "(unknown socket type)"; break; } ss << ":" << mLocalAddr.getPort(); return ss.str();}void NetControl::InitSimulation(){ // assert that the local port has been set if (mLocalAddr.getPort() == INADDR_ANY) { GetLog()->Error() << "(NetControl) ERROR: local port has no been set in '" << GetClass()->GetName() << "'\n"; return; } GetLog()->Normal() << "(NetControl) '" << GetName() << "' setting up a server on " << DescribeSocketType() << std::endl; mSocket = CreateSocket(mSocketType); if (mSocket.get() == 0) { return; } int ret = mSocket->setNonBlocking(true); if (ret < 0) { GetLog()->Error() << "(NetControl) failed to set server socket to non " << "blocking mode with '" << strerror(errno) << "'\n"; mSocket->close(); return; } try { mSocket->bind(mLocalAddr); } catch (BindErr error) { GetLog()->Error() << "(NetControl) failed to bind socket with '" << error.what() << "'" << endl; mSocket->close(); return; } try { if (mSocketType == ST_TCP) {#ifdef SOMAXCONN mSocket->listen(SOMAXCONN);#else mSocket->listen(50);#endif } } catch (ListenErr error) { GetLog()->Error() << "(NetControl) failed to listen on socket with '" << error.what() << "'" << endl; mSocket->close(); return; } // assure that a NetMessage object is registered mNetMessage = FindChildSupportingClass<NetMessage>(); if (mNetMessage.get() == 0) { mNetMessage = shared_ptr<NetMessage>(new NetMessage()); }}void NetControl::DoneSimulation(){ // reset the cached NetMessage reference mNetMessage.reset(); // close all client connections for ( TAddrMap::iterator iter = mClients.begin(); iter != mClients.end(); ++iter ) { RemoveClient((*iter).second->addr); } // shutdown the server socket mSocket->close(); GetLog()->Normal() << "(NetControl) '" << GetName() << "' closed server socket " << DescribeSocketType() << std::endl; mSocket.reset(); mClients.clear();}void NetControl::AddClient(const Addr& from, shared_ptr<Socket> socket){ shared_ptr<Client> client(new Client(mClientId,from,socket)); mClients[from] = client; GetLog()->Normal() << "(NetControl) '" << GetName() << "' accepted a " << ((socket.get() != 0) ? "TCP" : "UDP") << " connection from '" << from.getHostStr() << ":" << from.getPort() << "' id " << mClientId << endl; mClientId++; ClientConnect(client);}void NetControl::RemoveClient(const Addr& from){ TAddrMap::iterator mapIter = mClients.find(from); if (mapIter == mClients.end()) { GetLog()->Warning() << "(NetControl) '" << GetName() << "' RemoveClient called with an unknown client address\n"; return; } shared_ptr<Client> client = (*mapIter).second; ClientDisconnect(client); shared_ptr<Socket> socket = client->socket; GetLog()->Normal() << "(NetControl) '" << GetName() << "' closing a " << ((socket.get() != 0) ? "TCP" : "UDP") << " connection from '" << from.getHostStr() << ":" << from.getPort() << "' id " << client->id << endl; if (socket.get() != 0) { socket->close(); } mClients.erase(mapIter);}void NetControl::ClientConnect(shared_ptr<Client> /*client*/){ // empty callback, implemented in derived classes}void NetControl::ClientDisconnect(shared_ptr<Client> /*client*/){ // empty callback, implemented in derived classes}void NetControl::SendMessage(shared_ptr<Client> client, const string& msg){ if (client.get() == 0) { return; } int rval = 0; shared_ptr<Socket> socket = client->socket; if (socket.get() == 0) { // udp client if (mSocket.get() != 0) { rval = mSocket->send(msg.data(), msg.size(), client->addr); } } else { // tcp client rval = socket->send(msg.data(), msg.size()); } if (rval < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -