//============================================================================== std::shared_ptr<Socket> SocketImpl::Accept() const noexcept { auto ret = std::make_shared<SocketImpl>(m_protocol, m_spConfig); struct sockaddr_in socketAddress; auto *pSocketAddress = reinterpret_cast<sockaddr *>(&socketAddress); socklen_t socketAddressLength = sizeof(socketAddress); socket_type skt = ::accept(m_socketHandle, pSocketAddress, &socketAddressLength); if (skt == InvalidSocket()) { SLOGS(m_socketHandle, "Error accepting"); ret.reset(); } else { SLOGD( m_socketHandle, "Accepted new socket: %d (%d)", ret->GetSocketId(), skt); ret->m_socketHandle = skt; ret->m_clientIp = ntohl(socketAddress.sin_addr.s_addr); ret->m_clientPort = ntohs(socketAddress.sin_port); ret->m_aConnectedState.store(ConnectedState::Connected); } return ret; }
void Messenger::Broadcast(const Message& m) const { try { for (SocketCollection::const_iterator sid=fSocketsConnected.begin(); sid!=fSocketsConnected.end(); sid++) { if (sid->first==GetSocketId()) continue; Send(m, sid->first); } } catch (Exception& e) { e.Dump(); } }
void Messenger::Receive() { Message msg; SocketMessage m; // We start by copying the master file descriptors list to the // temporary list for readout fReadFds = fMaster; try { SelectConnections(); } catch (Exception& e) { e.Dump(); throw Exception(__PRETTY_FUNCTION__, "Impossible to select the connections!", Fatal); } // Looking for something to read! for (SocketCollection::const_iterator s=fSocketsConnected.begin(); s!=fSocketsConnected.end(); s++) { if (!FD_ISSET(s->first, &fReadFds)) continue; // First check if we need to handle new connections if (s->first==GetSocketId()) { AddClient(); return; } // Handle data from a client try { msg = FetchMessage(s->first); } catch (Exception& e) { //std::cout << "exception found..." << e.OneLine() << ", "<< e.ErrorNumber() << std::endl; e.Dump(); if (e.ErrorNumber()==11000) { DisconnectClient(s->first, THIS_CLIENT_DELETED); return; } } m = SocketMessage(msg.GetString()); // Message was successfully decoded fNumAttempts = 0; try { ProcessMessage(m, s->first); } catch (Exception& e) { if (e.ErrorNumber()==11001) break; } } }
void Client::Receive() { SocketMessage msg; try { msg = FetchMessage(); } catch (Exception& e) { if (e.ErrorNumber()==11000) // client has been disconnected throw Exception(__PRETTY_FUNCTION__, "Some other socket asked for this client's disconnection. Obtemperating...", Fatal); } if (msg.GetKey()==MASTER_DISCONNECT) { throw Exception(__PRETTY_FUNCTION__, "Master disconnected!", Fatal); } else if (msg.GetKey()==OTHER_CLIENT_DELETED) { throw Exception(__PRETTY_FUNCTION__, "Some other socket asked for this client's disconnection. Obtemperating...", Fatal); } else if (msg.GetKey()==GET_CLIENT_TYPE) { Send(SocketMessage(CLIENT_TYPE, static_cast<int>(GetType()))); } else if (msg.GetKey()==PING_CLIENT) { std::ostringstream os; os << "Pong. My name is " << GetSocketId() << " and I feel fine, thank you!"; Send(SocketMessage(PING_ANSWER, os.str())); PrintInfo("Got a ping, answering..."); } else if (msg.GetKey()==CLIENTS_LIST) { VectorValue vals = msg.GetVectorValue(); int i = 0; std::ostringstream o; o << "List of members on the socket:\n\t"; for (VectorValue::const_iterator v=vals.begin(); v!=vals.end(); v++, i++) { if (i!=0) o << ", "; o << *v; } PrintInfo(o.str()); } else { ParseMessage(msg); } }
void Messenger::ProcessMessage(SocketMessage m, int sid) { if (m.GetKey()==REMOVE_CLIENT) { if (m.GetIntValue()==GetSocketId()) { std::ostringstream o; o << "Some client (id=" << sid << ") asked for this master's disconnection!" << "\n\tIgnoring this request..."; throw Exception(__PRETTY_FUNCTION__, o.str(), JustWarning); return; } const MessageKey key = (sid==m.GetIntValue()) ? THIS_CLIENT_DELETED : OTHER_CLIENT_DELETED; DisconnectClient(m.GetIntValue(), key); throw Exception(__PRETTY_FUNCTION__, "Removing socket client", Info, 11001); } else if (m.GetKey()==PING_CLIENT) { const int toping = m.GetIntValue(); Send(SocketMessage(PING_CLIENT), toping); SocketMessage msg; int i=0; do { msg = FetchMessage(toping); i++; } while (msg.GetKey()!=PING_ANSWER && i<MAX_SOCKET_ATTEMPTS); try { Send(SocketMessage(PING_ANSWER, msg.GetValue()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==GET_CLIENTS) { int i = 0; std::ostringstream os; for (SocketCollection::const_iterator it=fSocketsConnected.begin(); it!=fSocketsConnected.end(); it++, i++) { if (i!=0) os << ";"; os << it->first << " (type " << static_cast<int>(it->second) << ")"; } try { Send(SocketMessage(CLIENTS_LIST, os.str()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==WEB_GET_CLIENTS) { int i = 0; SocketType type; std::ostringstream os; for (SocketCollection::const_iterator it=fSocketsConnected.begin(); it!=fSocketsConnected.end(); it++, i++) { type = (it->first==GetSocketId()) ? MASTER : it->second; if (i!=0) os << ";"; os << it->first << ","; if (it->first==GetSocketId()) os << "Master,"; else os << "Client" << it->first << ","; os << static_cast<int>(type) << "\0"; } try { Send(SocketMessage(CLIENTS_LIST, os.str()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==START_ACQUISITION) { try { StartAcquisition(); } catch (Exception& e) { e.Dump(); SendAll(DAQ, e); } } else if (m.GetKey()==STOP_ACQUISITION) { try { StopAcquisition(); } catch (Exception& e) { e.Dump(); SendAll(DAQ, e); } } else if (m.GetKey()==NEW_RUN) { try { OnlineDBHandler().NewRun(); int last_run = OnlineDBHandler().GetLastRun(); SendAll(DQM, SocketMessage(RUN_NUMBER, last_run)); SendAll(DAQ, SocketMessage(RUN_NUMBER, last_run)); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==GET_RUN_NUMBER) { int last_run = 0; try { last_run = OnlineDBHandler().GetLastRun(); } catch (Exception& e) { last_run = -1; } try { Send(SocketMessage(RUN_NUMBER, last_run), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==SET_NEW_FILENAME) { try { std::cout << "---> " << m.GetValue() << std::endl; SendAll(DQM, SocketMessage(NEW_FILENAME, m.GetValue().c_str())); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==NUM_TRIGGERS or m.GetKey()==HV_STATUS) { try { SendAll(DAQ, m); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==NEW_DQM_PLOT or m.GetKey()==UPDATED_DQM_PLOT) { try { SendAll(DAQ, m); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==EXCEPTION) { try { SendAll(DAQ, m); std::cout << "--> " << m.GetValue() << std::endl; } catch (Exception& e) { e.Dump(); } } /*else { try { Send(SocketMessage(INVALID_KEY), sid); } catch (Exception& e) { e.Dump(); } std::ostringstream o; o << "Received an invalid message: " << m.GetString(); throw Exception(__PRETTY_FUNCTION__, o.str(), JustWarning); }*/ }