static const short kDefaultPort = 12345;
static const int kWrongArgumentCount = 1;
static const int kServerStartFailure = 2;
int main(int argc, char *argv[]) {
if (argc > 1) {
cerr << "Usage: " << argv[0] << endl;
return kWrongArgumentCount;
}
int serverSocket = createServerSocket(kDefaultPort);
if (serverSocket == kServerSocketFailure) {
cerr << "Error: Could not start server on port " << kDefaultPort << "." << endl;
cerr << "Aborting... " << endl;
return kServerStartFailure;
}
cout << "Server listening on port " << kDefaultPort << "." << endl;
while (true) {
int clientSocket = accept(serverSocket, NULL, NULL);
publishTime(clientSocket);
}
return 0;
}static void publishTime(int clientSocket) {
time_t rawtime;
time(&rawtime);
struct tm *ptm = gmtime(&rawtime);
char timeString[128]; // more than big enough
/* size_t len = */ strftime(timeString, sizeof(timeString), "%c\n", ptm);
size_t numBytesWritten = 0, numBytesToWrite = strlen(timeString);
while (numBytesWritten < numBytesToWrite) {
numBytesWritten += write(clientSocket,
timeString + numBytesWritten,
numBytesToWrite - numBytesWritten);
}
close(clientSocket);
}
int main(int argc, char *argv[]) {
if (argc > 1) {
cerr << "Usage: " << argv[0] << endl;
return kWrongArgumentCount;
}
int serverSocket = createServerSocket(kDefaultPort);
if (serverSocket == kServerSocketFailure) {
cerr << "Error: Could not start time server to listen to port " << kDefaultPort << "." << endl;
cerr << "Aborting... " << endl;
return kServerStartFailure;
}
cout << "Server listening on port " << kDefaultPort << "." << endl;
ThreadPool pool(4);
while (true) {
int clientSocket = accept(serverSocket, NULL, NULL);
pool.schedule([clientSocket] { publishTime(clientSocket); });
}
return 0;
}
static void publishTime(int clientSocket) {
time_t rawtime;
time(&rawtime);
struct tm tm;
gmtime_r(&rawtime, &tm);
char timeString[128]; // more than big enough
/* size_t len = */ strftime(timeString, sizeof(timeString), "%c", &tm);
sockbuf sb(clientSocket); // destructor closes socket
iosockstream ss(&sb);
ss << timeString << endl;
}static void publishTime(int clientSocket) {
time_t rawtime;
time(&rawtime);
struct tm *ptm = gmtime(&rawtime);
char timeString[128]; // more than big enough
/* size_t len = */ strftime(timeString, sizeof(timeString), "%c", ptm);
sockbuf sb(clientSocket);
iosockstream ss(&sb);
ss << timeString << endl;
} // the sockbuf closes the socket when it's destroyed
int main(int argc, char *argv[]) {
int clientSocket = createClientSocket("myth7.stanford.edu", 12345);
if (clientSocket == kClientSocketError) {
cerr << "Time server could not be reached" << endl;
cerr << "Aborting" << endl;
return 1;
}
sockbuf sb(clientSocket);
iosockstream ss(&sb);
string timeline;
getline(ss, timeline);
cout << timeline << endl;
return 0;
}
static const string kProtocolPrefix = "http://";
static const string kDefaultPath = "/";
static pair<string, string> parseURL(string url) {
if (startsWith(url, kProtocolPrefix)) // in "string-utils.h"
url = url.substr(kProtocolPrefix.size());
size_t found = url.find('/');
if (found == string::npos)
return make_pair(url, kDefaultPath); // defined in <utility>
string host = url.substr(0, found);
string path = url.substr(found);
return make_pair(host, path);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
cerr << "Usage: " << argv[0] << " <url>" << endl;
return kWrongArgumentCount;
}
pullContent(parseURL(argv[1]));
return 0;
}
static void pullContent(const pair<string, string>& components) {
int clientSocket = createClientSocket(components.first, 80);
// error checking omitted
sockbuf sb(clientSocket);
iosockstream ss(&sb);
issueRequest(ss, components.first, components.second);
skipHeader(ss);
savePayload(ss, getFileName(components.second));
}
static void issueRequest(iosockstream& ss, const string& host, const string& path) {
ss << "GET " << path << " HTTP/1.0\r\n";
ss << "Host: " << host << "\r\n";
ss << "\r\n";
ss.flush();
}
static void skipHeader(iosockstream& ss) {
string line;
do {
getline(ss, line);
} while (!line.empty() && line != "\r");
}
static string getFileName(const string& path) {
if (path.empty() || path[path.size() - 1] == '/') {
return "index.html"; // not always correct, but not the point
}
size_t found = path.rfind('/');
return path.substr(found + 1);
}
static const size_t kBufferSize = 1024; // just a random, large size
static void savePayload(iosockstream& ss, const string& filename) {
ofstream output(filename, ios::binary); // don't assume it's text
size_t totalBytes = 0;
while (!ss.fail()) {
char buffer[kBufferSize] = {'\0'};
ss.read(buffer, sizeof(buffer));
totalBytes += ss.gcount();
output.write(buffer, ss.gcount());
}
cout << "Total number of bytes fetched: " << totalBytes << endl;
}