Simple Half-Duplex Chat
/* * 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; } }