📄 sfcontrol.cpp
字号:
int baudrate = 0;
int port = 0;
helpInt << tokens[3] << " " << tokens[1];
helpInt >> baudrate >> port;
startServer(port, tokens[2], baudrate);
}
else
{
os << ">> FAIL: Too many running servers (currently " << servers.size() << " servers running)" << endl;
deliverOutput();
}
}
else
{
os << getHelpMessage("start");
deliverOutput();
}
}
else if (tokens[0] == "stop")
{
if (tokens.size() == 2)
{
stringstream helpInt;
int port = 0;
int id = -1;
helpInt << tokens[1] << " " << tokens[1];
helpInt >> id >> port;
if (!stopServer(id, port, tokens[1]))
{
os << ">> no sf-server with id / device / baudrate = " << tokens[1] << " found!" << endl;
deliverOutput();
}
else
{
os << ">> stopped sf-server with id = " << id
<< " ( port = " << port
<< " , device = " << tokens[1]
<< " )" << endl;
deliverOutput();
}
}
else
{
os << getHelpMessage("stop");
deliverOutput();
}
}
else if (tokens[0] == "info")
{
if (tokens.size() == 2)
{
stringstream helpInt;
int port = 0;
int id = -1;
helpInt << tokens[1] << " " << tokens[1];
helpInt >> id >> port;
if (!showServerInfo(os, id, port, tokens[1]))
{
os << ">> no sf-server with id / device / baudrate = " << tokens[1] << " found!" << endl;
deliverOutput();
} else {
deliverOutput();
}
}
else
{
os << getHelpMessage("info");
deliverOutput();
}
}
else if ((tokens[0] == "close") && (controlServerStarted))
{
if (clientFD > 0) {
os << ">> closing connection to control-client " << endl;
deliverOutput();
close(clientFD);
clientFD = -1;
}
}
else if (tokens[0] == "list")
{
os << ">> currently running sf-servers:" << endl;
listServers(os);
deliverOutput();
}
else if (tokens[0] == "exit")
{
os << ">> exiting..." << endl;
deliverOutput();
exit(0);
}
else
{
if ((tokens[0] == "help") && (tokens.size() == 2))
{
os << getHelpMessage(tokens[1]);
deliverOutput();
}
else
{
os << getHelpMessage(tokens[0]);
deliverOutput();
}
}
}
/* send string to connected client.. */
bool SFControl::sendToClient(string message)
{
if (clientFD < 0)
return false;
int length = message.size();
const char* buffer = message.c_str();
while (length > 0)
{
#ifdef __APPLE__
int n = send(clientFD, buffer, length, 0);
#else
int n = send(clientFD, buffer, length, MSG_NOSIGNAL);
#endif
if (!(n > 0))
{
return false;
}
length -= n;
buffer += n;
}
return true;
}
/* receive string from connected client... */
bool SFControl::readFromClient(string& message)
{
if (clientFD < 0)
return false;
int length = 0;
char buffer[256];
char* bufPtr = buffer;
*bufPtr = '\0';
do
{
int n = read(clientFD, (void *) bufPtr, 1);
if (!(n > 0))
{
return false;
}
}
while ((*bufPtr++ != '\n') && (length++ < 255));
buffer[length] = '\0';
message = (length == 1) ? "" : buffer;
return true;
}
void SFControl::waitOnInput()
{
bool clientConnected = false;
struct sockaddr_in client;
socklen_t clientAddrLen = sizeof(client);
FD_ZERO(&rfds);
while (true)
{
int maxfd = 0;
if(daemon) {
FD_CLR(0, &rfds);
}
else {
FD_SET(0, &rfds);
}
if (controlServerStarted)
{
FD_SET(serverFD, &rfds);
maxfd = (serverFD > maxfd) ? serverFD : maxfd;
}
if (clientConnected)
{
FD_SET(clientFD, &rfds);
maxfd = (clientFD > maxfd) ? clientFD : maxfd;
}
reportError("SFControl::waitOnInput : select(maxfd+1, &rfds, NULL, NULL, NULL)", select(maxfd+1, &rfds, NULL, NULL, NULL));
if (FD_ISSET(0, &rfds))
{
/* parse standard input */
FD_CLR(0, &rfds);
string input = "";
getline (cin, input);
if (input != "")
{
os << "standard input : " << input << endl;
if (!(clientFD < 0))
sendToClient(os.str());
os.str("");
os.clear();
parseInput(input);
}
}
if (clientFD == -1) clientConnected = false;
if (controlServerStarted)
{
if (FD_ISSET(serverFD, &rfds))
{
/* we got a new connection request */
FD_CLR(serverFD, &rfds);
int newClientFD = reportError("SFControl::waitOnInput : accept(serverFD, (struct sockaddr*) &client, &clientAddrLen)", accept(serverFD, (struct sockaddr*) &client, &clientAddrLen));
if ((newClientFD >= 0) && (!clientConnected))
{
clientFD = newClientFD;
clientConnected = true;
os << ">> accepted connection from control-client " << inet_ntoa(client.sin_addr) << endl;
deliverOutput();
}
else
{
close(newClientFD);
}
}
}
if (clientConnected)
{
if (FD_ISSET(clientFD, &rfds))
{
/* we got data from the connected control client */
FD_CLR(clientFD, &rfds);
string input = "";
if (readFromClient(input))
{
if (input != "")
{
os << "control-client : " << input << endl;
cout << os.str();
os.str("");
os.clear();
parseInput(input);
}
}
else
{
os << ">> closing connection to control-client " << inet_ntoa(client.sin_addr) << endl;
deliverOutput();
close(clientFD);
clientFD = -1;
}
}
}
if (clientFD == -1) clientConnected = false;
}
}
void* checkCancelThread(void* ob)
{
static_cast<SFControl*>(ob)->checkThreadCancel();
return NULL;
}
/* keeps track of self-canceled sf-servers */
void SFControl::checkThreadCancel()
{
while(true)
{
pthread_testcancel();
pthread_mutex_lock(&sfControlInfo.lock);
pthread_cond_wait(&sfControlInfo.cancel, &sfControlInfo.lock);
list<sfServer_t>::iterator it = servers.begin();
list<sfServer_t>::iterator next = it;
while( it != servers.end() )
{
++next;
if ((*it).TcpServer->isErrorReported() || (*it).SerialDevice->isErrorReported())
{
// cancel
(*it).TcpServer->cancel();
(*it).SerialDevice->cancel();
// inform user
os << ">> FAIL: sf-server with id = " << (*it).id
<< " ( port = " << (*it).TcpServer->getPort()
<< " , device = " << (*it).SerialDevice->getDevice()
<< " ) canceled" << endl;
deliverOutput();
// clean up
delete (*it).TcpServer;
delete (*it).SerialDevice;
delete (*it).tcp2serial;
delete (*it).serial2tcp;
servers.erase(it);
}
it = next;
}
pthread_mutex_unlock(&sfControlInfo.lock);
}
}
void SFControl::startControlServer()
{
struct sockaddr_in me;
int opt = 1;
serverFD = reportError("SFControl::startControlServer : socket(AF_INET, SOCK_STREAM, 0)", socket(AF_INET, SOCK_STREAM, 0));
reportError("SFControl::startControlServer : fcntl(serverFD, F_SETFL, O_NONBLOCK)", fcntl(serverFD, F_SETFL, O_NONBLOCK));
memset(&me, 0, sizeof me);
me.sin_family = AF_INET;
me.sin_port = htons(controlPort);
reportError("SFControl::startControlServer : setsockopt(serverFD, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))", setsockopt(serverFD, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)));
reportError("SFControl::startControlServer : bind(serverFD, (struct sockaddr *)&me, sizeof me)", bind(serverFD, (struct sockaddr *)&me, sizeof me));
reportError("SFControl::startControlServer : listen(serverFD, 1)", listen(serverFD, 1));
controlServerStarted = true;
}
void SFControl::deliverOutput()
{
if (!(clientFD < 0))
sendToClient(os.str());
cout << os.str();
os.str("");
os.clear();
}
/* reports error */
int SFControl::reportError(const char *msg, int result)
{
if (result < 0)
{
cerr << "FATAL : SF-Control-Server : "
<< msg << " ( result = " << result << " )" << endl
<< "error-description : " << strerror(errno) << endl;
exit(1);
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -