//================================================================ // chatd.cc // Web browserをクライアントとするチャットデーモン // Copyright (C) Naoki Watanabe. 1999-2000. All rights reserved. //================================================================ #include #include #include #include #include #include #include #include // Port number of this chat server. const int CHAT_PORT = 1080; // Maximum number of clients at the same time. const int MAX_CLIENTS = 16; // Size of data buffer. const int BUF_SIZE = 1024; //---- Definition of class Socket. class Socket { int sc; // socket descriptor. sockaddr_in addr; // address of the socket. public: //-- default constructor. Socket( void ) : sc(0) { } //-- constructor for the base socket. Socket( const u_short port ){ sc = socket( AF_INET, SOCK_STREAM, 0 ); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(port); if( bind( sc, (sockaddr*)&addr, sizeof(sockaddr_in)) < 0 ){ perror("bind"); exit(1); } listen( sc, MAX_CLIENTS+1 ); } //-- destructor ~Socket(){ Close(); } //-- accept a new socket from the base socket. void Accept( const Socket& base ){ #if defined(_XOPEN_SOURCE_EXTENDED) size_t len = sizeof(sockaddr_in); #else int len = sizeof(sockaddr_in); #endif sc = accept( base.sc, (sockaddr*)&addr, &len ); } //-- receive a messege. void Recv( char buf[BUF_SIZE] ){ int len = read( sc, buf, BUF_SIZE ); buf[len] = '\0'; } //-- send a messege. void Send( char* buf ){ // An error means the disconnection of the socket by the client // if SIGPIPE signal does not stop this process. if( write( sc, buf, strlen(buf) ) < 0 ) Close(); } //-- close this socket. void Close( void ){ close(sc); sc = 0; } //-- check if the socket is connecting. int IsActive( void ){ return sc!=0; } //-- return the remote address of this connection. struct in_addr RemoteAddr( void ){ // return the IP in network order. return addr.sin_addr; } //-- return the remote port of this connection. u_short RemotePort( void ){ // return the Port in localhost order. return ntohs(addr.sin_port); } }; int main( void ) { Socket base(CHAT_PORT); // socket for listening. Socket from; // socket for accepting. Socket to[MAX_CLIENTS]; // socket for sending. char buf[BUF_SIZE]; // data buffer. char msg[BUF_SIZE]; // data buffer. signal( SIGPIPE, SIG_IGN ); // to escape from the broken pipe error. while(1){ from.Accept(base); from.Recv(buf); // may receive the GET request line. if( 1 == sscanf( buf, "GET /submit?messege=%s", msg ) ){ //---- block for the submittion. // send a noresponse header to the submit frame. from.Send( "HTTP/1.0 204 No Response\n\n" ); from.Close(); // send the messege to the content frames of all browsers. snprintf( buf, sizeof(buf), "%s.%d: %s
\n", inet_ntoa(from.RemoteAddr()), from.RemotePort(), msg ); for( int i=0; i\n" "\n" "\n" "\n" ); from.Close(); }else if( !strncmp( buf, "GET /input", 10 ) ){ //---- block for the input frame. from.Send( "HTTP/1.0 200 OK\n" "Content-type: text/html\n\n" "
" "" "" "" "
\n" ); from.Close(); }else if( !strncmp( buf, "GET /content", 10 ) ){ //---- block for the content frame. int i; // search an unoccupied socket. for( i=0; iSorry, now this chat is too crowded.\n" ); from.Close(); }else{ // entry the socket, make a greeting. to[i] = from; to[i].Send( "HTTP/1.0 200 OK\n" "Content-type: text/html\n" "\n" "\n" "\n" "\n" "
\n"
		    "=========================================\n"
	            "   Web-independent smart chat server.    \n"
		    "Originally designed by Naoki Watanabe.   \n"
		    "Last modified on Mar 12th, 2000 by Naoki.\n"
		    "=========================================\n"
		    "
\n" ); } }else{ //---- block for an illegal call. from.Send( "HTTP/1.0 200 OK\n" "Content-type: text/html\n\n" "

Illegal access.

\n" ); from.Close(); } } return 0; }