/*
* Very simple line-oriented half-duplex chat program. If the command
* line contains just a port number, operates as a server and listens for
* connections on that port. With a host and port, attempts to connect and
* plays the client. Alternately reads a line from the console and sends it,
* then reads a line from the network and print it. The client side reads
* console first.
*/
#include <cstdlib>
#include <iostream>
#include <cleansocks.h>
#include <cleanip.h>
#include <cleanbuf.h>
using std::string;
using namespace cleansocks;
/*
* Prompt and read a line, and send it. Return success
*/
bool dosend(buffered_socket &s)
{
std::cout << " >> ";
string line;
if(!std::getline(std::cin,line)) return false;
send(s, line+"\n");
return true;
}
/*
* Read a line from the network and print it. Return success
*/
bool dorecv(buffered_socket &s)
{
char buf[1024];
int nc = recvln(s, buf, sizeof buf);
if(nc == 0) return false;
std::cout << " << " << string(buf, nc); // Newline at end of buf.
return true;
}
int main(int argc, char **argv)
{
// Figure out what's on the command line, and how to start.
TCPsocket talker;
bool rcv_first;
if(argc == 2) {
// Just a port number. We're a server.
IPport port = atoi(argv[1]);
TCPsocket listener;
bind(listener, IPendpoint(IPaddress::any(),port));
listen(listener);
talker = accept(listener);
close(listener);
rcv_first = true;
} else if(argc == 3) {
// Host and port. We're a client.
IPaddress addr = lookup_host(argv[1]);
IPport port = atoi(argv[2]);
connect(talker, IPendpoint(addr, port));
rcv_first = false;
} else {
// Ooops!
std::cerr << "Usage " << argv[0] << "[ host ] port"
<< std::endl;
exit(1);
}
// Buffering is nice for this.
buffered_socket bsock(talker);
// If we're the server, we need to receive first. The main
// loop sends first, so we we sneak in a extra receive here,
// all will be fine.
if(rcv_first)
if(!dorecv(bsock))
exit(0);
// Exchange messages.
while(true) {
if(!dosend(bsock)) break;
if(!dorecv(bsock)) break;
}
}