📄 appclient.cpp
字号:
//// The contents of this file are subject to the Mozilla Public// License Version 1.1 (the "License"); you may not use this file// except in compliance with the License. You may obtain a copy// of the License at http://www.mozilla.org/MPL/// // Software distributed under the License is distributed on an// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or// implied. See the License for the specific language governing// rights and limitations under the License.// // The Original Code is State Machine Compiler (SMC).// // The Initial Developer of the Original Code is Charles W. Rapp.// Portions created by Charles W. Rapp are// Copyright (C) 2000 - 2007. Charles W. Rapp.// All Rights Reserved.// // Contributor(s): //// Name// AppClient.cpp//// Description// TcpClient listener object.//// RCS ID// $Id: AppClient.cpp,v 1.6 2007/12/28 12:34:40 cwrapp Exp $//// CHANGE LOG// $Log: AppClient.cpp,v $// Revision 1.6 2007/12/28 12:34:40 cwrapp// Version 5.0.1 check-in.//// Revision 1.5 2005/05/28 13:31:18 cwrapp// Updated C++ examples.//// Revision 1.0 2003/12/14 19:34:34 charlesr// Initial revision//#include "AppClient.h"#include "AppServer.h"#include "Eventloop.h"#if defined(WIN32)#include <winsock2.h>#include <iostream>#include <time.h>#else#include <arpa/inet.h>#endif#include <stdlib.h>#include <memory.h>using namespace std;// Externally defined global variables.extern Eventloop *Gevent_loop;// Class variables.int AppClient::_initFlag = 0;const long AppClient::MIN_SLEEP_TIME = 100;const long AppClient::MAX_SLEEP_TIME = 30000;//---------------------------------------------------------------// AppClient() (Public)// Default constructor.//AppClient::AppClient(): _client_socket(NULL), _owner(NULL), _host(), _messageCount(0){}//---------------------------------------------------------------// AppClient(const char*, TcpClient&, AppServer&) (Public)// An "accept" construct.//AppClient::AppClient(const string& host, TcpClient& tcp_client, AppServer& owner): _client_socket(&tcp_client), _owner(&owner), _host(host), _messageCount(0){ // Tell the client that this object is now listening to it. tcp_client.setListener(*this); // Since this client is already connected, set the // random transmit timer. setTransmitTimer(); return;} // end of AppClient::AppClient(TcpClient&, AppServer&)//---------------------------------------------------------------// ~AppClient() (Public)// Destructor.//AppClient::~AppClient(){ if (_client_socket != NULL) { delete _client_socket; _client_socket = NULL; } return;} // end of AppClient::~AppClient()//---------------------------------------------------------------// getHost() const (Public)// Return the host name.//const string& AppClient::getHost() const{ return(_host);} // end of AppClient::getHost() const//---------------------------------------------------------------// open(const string&, const sockaddr_in&) (Public)// Open a connection to the named TCP service.//void AppClient::open(const string& host, const sockaddr_in& address){ if (_client_socket == NULL) { // Store away the host name. _host = host; cout << "Opening connection to " << host << ":" << ntohs(address.sin_port) << " ... "; // Create the client object and open it. _client_socket = new TcpClient(*this); _client_socket->open(address); } return;} // end of AppClient::open(const string&, const sockaddr_in&)//---------------------------------------------------------------// close() (Public)// Close the client connection.//void AppClient::close(){ if (_client_socket != NULL) { cout << "Closing connection to " << _host << ":" << ntohs((_client_socket->getServerAddress()).sin_port) << " ... "; _client_socket->doClose(); } return;} // end of AppClient::close()//---------------------------------------------------------------// opened(TcpConnection&) (Public)// TCP client connection successful.//void AppClient::opened(TcpConnection&){ cout << "open successful." << endl; // Set the transmit timer. setTransmitTimer(); return;} // end of AppClient::opened(TcpConnection&)//---------------------------------------------------------------// openFailed(const char*, TcpConnection&) (Public)// TCP client connection failed.//void AppClient::openFailed(const char *reason, TcpConnection&){ void socketClosed(); cout << "open failed"; if (reason == NULL) { cout << "." << endl; } else { cout << " - " << reason << endl; } // Let the application know that the socket is closed. socketClosed(); return;} // end of AppClient::openFailed(const char*, TcpConnection&)//---------------------------------------------------------------// transmitted(TcpConnection&) (Public)// Data successfully transmitted.//void AppClient::transmitted(TcpConnection&){ // Set the timer for the next transmission. setTransmitTimer(); cout << "transmit successful." << endl; return;} // end of AppClient::transmitted(TcpConnection&)//---------------------------------------------------------------// transmitFailed(const char*, TcpConnection&) (Public)// Failed to send data to far-end.//void AppClient::transmitFailed(const char *reason, TcpConnection&){ cout << "transmit failed - " << reason << "." << endl; return;} // end of AppClient::transmitFailed(const char*, TcpConnection&)//---------------------------------------------------------------// receive(const char*, int, TcpConnection&) (Public)// Received data from far end.//void AppClient::receive(const char *data, int size, TcpConnection&){ const sockaddr_in& address = _client_socket->getServerAddress(); char *string = new char[size + 1]; // Turn the data into a string. (void) memcpy(string, data, size); string[size] = '\0'; cout << "Received data from " << inet_ntoa(address.sin_addr) << ":" << ntohs(address.sin_port) << ": \"" << string << "\"" << endl; delete[] string; return;} // end of AppClient::receive(const char*, int, TcpConnection&)//---------------------------------------------------------------// halfClosed(TcpConnection&) (Public)// This far end has closed its connection. Close down this side.//void AppClient::halfClosed(TcpConnection&){ const sockaddr_in& address = _client_socket->getServerAddress(); cout << "Connection from " << _host << ":" << address.sin_port << " has closed its side." << endl << "Closing connection to " << _host << ":" << ntohs(address.sin_port) << " ... "; // Stop the transmit timer if running. Gevent_loop->stopTimer("TRANSMIT_TIMER", *this); // When this timer expires, close this end of the connection, // after waiting one millisecond. Gevent_loop->startTimer("CLOSE_TIMER", 1, *this); return;} // end of AppClient::halfClosed(TcpConnection&)//---------------------------------------------------------------// closed(const char*, TcpConnection&) (Public)// This client connection is closed.//void AppClient::closed(const char*, TcpConnection&){ void socketClosed(); cout << "closed." << endl; // Stop the transmit timer if running. Gevent_loop->stopTimer("TRANSMIT_TIMER", *this); // If this is an accepted connection, tell the service owner // that this connection is gone. if (_owner != NULL) { _owner->clientClosed(*this); } else { // Tell the client application that this connection is // closed. socketClosed(); } return;} // end of AppClient::closed(const char*, TcpConnection&)//---------------------------------------------------------------// handleTimeout(const char*) (Public)// Time to send another message.//void AppClient::handleTimeout(const char *name){ if (strcmp(name, "TRANSMIT_TIMER") == 0) { char message[30]; const sockaddr_in& address = _client_socket->getServerAddress(); (void) sprintf(message, "This is message #%d.", ++_messageCount); cout << "Transmitting to " << _host << ":" << ntohs(address.sin_port) << ": \"" << message << "\" ... "; _client_socket->transmit(message, 0, strlen(message)); } else if (strcmp(name, "CLOSE_TIMER") == 0) { _client_socket->doClose(); } return;} // end of AppClient::handleTimeout(const char*)//---------------------------------------------------------------// setTransmitTimer() (Private)// Set the transmit timer to expire some random time in the// future.//void AppClient::setTransmitTimer(){ long duration; // Initialize the random number generator, if necessary. if (_initFlag == 0) { srand(time(NULL)); _initFlag = 1; } // Set the next tranmission to some random time. duration = ((long) rand()) % MAX_SLEEP_TIME; if (duration < MIN_SLEEP_TIME) { duration = MIN_SLEEP_TIME; } Gevent_loop->startTimer("TRANSMIT_TIMER", duration, *this); return;} // end of AppClient::setTransmitTimer()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -