Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Daniel DePaolo
- // 10-25-10
- // CS 450
- // Server.cpp
- // C++ libs
- #include <string>
- #include <iostream>
- #include <ctime>
- #include <cerrno>
- #include <cstdlib>
- #include <cstdio>
- // C libs
- #include "sys/types.h"
- #include "sys/socket.h"
- #include "netinet/in.h"
- #include "arpa/inet.h"
- #include "strings.h"
- // My classes
- #include "ChatRoom.h"
- #include "Collections.h"
- #include "Client.h"
- using namespace std;
- #define PORT_NUMBER 5081
- #define MAXLINE 200
- #define MAXSIZE 512
- #define ACK 2
- #define NACK 3
- #define REQUESTMSGTRANSFER 100
- int writen(int sd, char *ptr, int size);
- int readn(int sd, char *ptr, int size);
- void *commandThread(void *sID);
- void *readerThread( void * clientObject);
- void *writerThread( void * clientObject);
- ClientCollection cliCol;
- ChatRoomCollection crCol;
- int main()
- {
- int listen_sd, conn_sd;
- struct sockaddr_in serv_addr, client_addr;
- socklen_t clilen = sizeof( client_addr );
- ChatRoom * Lobby = new ChatRoom("Lobby", "Lobby");
- crCol.addChatRoom(Lobby);
- cout<< "server: creating socket to listen for client"<< endl;
- if ((listen_sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- cout<< "server: socket error : "<< errno<< endl;
- exit(0);
- }
- cout<< "server: binding local socket"<< endl;
- bzero((char *) &serv_addr, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET; // Comm. using internet domain "AF_INET"
- serv_addr.sin_port = htons(PORT_NUMBER); // Which port does server listen on?
- serv_addr.sin_addr.s_addr = htons(INADDR_ANY); // Who can connect to server?
- if (bind (listen_sd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
- {
- perror( "Bind error" );
- exit(0);
- }
- cout<< "server: start listening"<< endl;
- if (listen (listen_sd, 6) < 0)
- {
- perror( "Listen error" );
- exit(0);
- }
- for ( ; ; )
- {
- // Accept a connection from a client
- cout<< "server: starting accept"<< endl;
- if ((conn_sd = accept(listen_sd, (struct sockaddr *) &client_addr, &clilen)) < 0)
- {
- perror( "Failed to accept" );
- exit(0);
- }
- // START COMMAND THREAD
- // -----------------------------
- commandThread((int*)listen_sd);
- }
- }
- void *commandThread( void *sID ) {
- // 1. Negotiate with the client to establish a name for the client.
- // 2. Create the client-object and add it to the list of clients.
- // 3. Block until both the reader and writer processes have been created.
- // 4. while( the client is active ) {
- // read a command from the client's socket.
- // carry out the command.
- // send a status back to the client.
- // }
- const int COMMAND_LEN = 4;
- int sockID = *(reinterpret_cast<int *>(sID));
- int msg_ok = 0;
- // negotiate with client to establish unique name
- string cliName;
- while (msg_ok == 0) {
- // get client name from the client
- cliName = " ";
- if (readn(sockID, (char *)cliName.c_str(), cliName.length()) < 0)
- {
- perror( "Read error" );
- exit(0);
- }
- // found client ID in list, negotiate for a new name
- if (cliCol.findClient(cliName) == false)
- msg_ok = 1;
- if (writen(sockID, (char *)&msg_ok, sizeof(msg_ok)) < 0)
- {
- perror( "Write error" );
- exit(0);
- }
- }
- // by here, unique ID has been established.
- // create client obj, add it to collection list
- Client * clientObj = new Client(cliName, crCol.getChatRoom("Lobby"));
- cliCol.addClient(clientObj);
- string command;
- int n;
- while( (n = readn( sockID, (char *)command.c_str(), COMMAND_LEN ) ) == COMMAND_LEN ) {
- command[ COMMAND_LEN ] = '\0';
- // Act on it.
- }
- // clean up!
- }
- /*
- // client's reader thread. The server writes to its socket!
- void *readerThread( void * clientObject) {
- Client *client = reinterpret_cast<Client *>(clientObject);
- int wDesc = client->getWriteSockDesc();
- while( client->isActive() ) {
- std::string msg = client->readMessage();
- // send this message to the client.
- flush( wDesc );
- }
- client.closeReader();
- }
- // client's writer thread. The server reads from it.
- void *writerThread( void * clientObject ) {
- Client *client = reinterpret_cast<Client *>(clientObject);
- while( client->isActive() ) {
- // read msg from the client's writer process
- client->postMessage( msg );
- }
- client->closeWriter();
- };
- */
- int readn(int sd, char *ptr, int size)
- {
- int no_left, no_read;
- no_left = size;
- while (no_left > 0)
- {
- no_read = read(sd, ptr, no_left);
- if (no_read < 0) return (no_read);
- if (no_read == 0) break;
- no_left -= no_read;
- ptr += no_read;
- }
- return (size - no_left);
- }
- int writen(int sd, char *ptr, int size)
- {
- int no_left, no_written;
- no_left = size;
- while (no_left > 0)
- {
- no_written = write(sd, ptr, no_left);
- if (no_written <= 0) return (no_written);
- no_left -= no_written;
- ptr += no_written;
- }
- return (size - no_left);
- }
- ///////////////////////////////////////////////////////
- // Daniel DePaolo
- // 10-25-10
- // CS 450
- // Client.h
- #ifndef CLIENT_H
- #define CLIENT_H
- #include <string>
- #include "BoundedBuffer.hpp"
- class ChatRoom;
- class Client {
- public:
- Client( std::string name, ChatRoom * defaultCR );
- std::string getID();
- bool isActive();
- void closeWriter();
- void closeReader();
- void setWriteSockDesc( int wsd );
- void setReadSockDesc( int rsd );
- void getWriteSockDesc();
- void getReadSockDesc();
- void setDefaultChatRoom( ChatRoom *chatRoom );
- ChatRoom *getDefaultChatRoom();
- // consumer thread:
- // Gets a message from the msgBox of the client to which this
- // object belongs and sends it to the client's reader
- // process. Notice that no reading takes place here. Instead, the
- // messages that are deposited into this client's "message box",
- // are taken out, one at a time, by this function and transmitted
- // to the reader process of this client.
- std::string readChatMessage();
- // producer thread:
- // adds a message to the msgBox of this client so that it can
- // ultimately be sent to the client through a call, by the thread
- // that represent the read process of the client, to the
- // "readChatMessage()".
- void writeChatMessage( std::string msg );
- // Post this message to the default chat-room of this client. The
- // thread that represents the writer process of the client that
- // this object serves, after having received a message from it,
- // calls this function to deliver the message for posting. These
- // messages are posted to the default chat-room of the client that
- // owns this object and not into the "message box" of this
- // client. However, the chat-room, after it receives the message,
- // ultimately calls the "writeChatMessage" of every client who has
- // subscribed to this chat-room, including this client.
- void postMessageToDefaultChatRoom( std::string msg );
- private:
- BoundedBuffer *msgBox;
- std::string clientID;
- int rSock, wSock;
- ChatRoom *defaultChatRoom;
- };
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement