Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.
#include "include/Sender.h"
#include "include/ChatMessage.h"
#include "include/AttentionMessage.h"
#include "include/ServerMessage.h"
#include "include/Socket.h"
#include "include/Client.h"
#include <string>
#include <vector>
#include <iostream>
Sender::Sender( Socket socket )
{
pthread_create(&m_thread, 0, &Sender::StartThread, this);
dataSocket = socket;
}
Sender::~Sender( )
{
}
std::string Sender::GetUsername( )
{
return m_username;
}
void Sender::run( )
{
std::string packedData;
std::cout << "Client/Server Chat" << std::endl;
std::cout << "Type the username: ";
std::getline( std::cin, m_username );
ServerMessage smsg;
smsg.SetUsername( m_username );
smsg.SetTime( );
packedData = smsg.Pack( );
dataSocket.SendData( packedData );
while( m_chatMessage != "/q" )
{
std::getline( std::cin, m_chatMessage );
if( m_chatMessage == "/a" )
{
AttentionMessage attmsg;
attmsg.SetUsername( m_username );
attmsg.SetTime( );
packedData = attmsg.Pack( );
dataSocket.SendData( packedData );
}
ChatMessage msg;
msg.SetMessage( m_chatMessage );
msg.SetUsername( m_username );
msg.SetTime( );
packedData = msg.Pack( );
dataSocket.SendData( packedData );
}
std::cout << "Bye." << std::endl;
dataSocket.Close( );
}
void * Sender::StartThread( void *arg )
{
reinterpret_cast<Sender *>(arg)->run( );
}
#include "include/ClientHandler.h"
#include "include/Socket.h"
#include "include/ServerDispatcher.h"
#include "include/ChatMessage.h"
#include "include/AttentionMessage.h"
#include "include/ServerMessage.h"
#include <string>
#include <vector>
#include <exception>
#include <iostream>
#include <pthread.h>
ClientHandler::ClientHandler( Socket socket )
{
pthread_create(&m_thread, 0, &ClientHandler::StartThread, this);
dataSocket = socket;
}
ClientHandler::~ClientHandler( )
{
}
void ClientHandler::SendMessage( std::string packedMessage )
{
m_ClientMessageQueue.push_front( packedMessage );
std::cout << "Message added to ClientHandler queue." << std::endl;
}
std::string ClientHandler::GetMessageFromQueue( )
{
while ( true )
{
if ( m_ClientMessageQueue.size( ) != 0 )
{
break;
}
}
std::string message = m_ClientMessageQueue.back( );
m_ClientMessageQueue.pop_back( );
return message;
}
void ClientHandler::run( )
{
char buffer[1024];
std::string message;
std::string packedMessage;
std::string rawMessage;
unsigned int result;
while ( true )
{
try
{
if ( dataSocket.DataCheck( ) > 0 )
{
try
{
if ( !dataSocket.RecvData( buffer ) )
{
break;
}
packedMessage = buffer;
result = packedMessage.find( "1" );
if ( result != std::string::npos && result < 2 )
{
ChatMessage msg;
msg.Unpack( packedMessage );
rawMessage = "[" + msg.GetTime( ) + "] " + msg.GetUsername( ) + ": " + msg.GetMessage( );
ServerDispatcher::Instance( ).DispatchMessage( rawMessage );
}
result = packedMessage.find( "2" );
if ( result != std::string::npos && result < 2 )
{
AttentionMessage attmsg;
attmsg.Unpack( packedMessage );
rawMessage = "[" + attmsg.GetTime( ) + "] " + attmsg.GetUsername( ) + " is asking for the ATTENTION of all chat members!!!";
ServerDispatcher::Instance( ).DispatchMessage( rawMessage );
}
result = packedMessage.find( "3" );
if ( result != std::string::npos && result < 2 )
{
ServerMessage smsg;
smsg.Unpack( packedMessage );
rawMessage = "[" + smsg.GetTime( ) + "] " + "SERVER: " + smsg.GetUsername( ) + " has logged in.";
ServerDispatcher::Instance( ).DispatchMessage( rawMessage );
}
memset( &buffer[0], 0, sizeof(buffer) );
}
catch ( std::exception &e )
{
std::cerr << "Connection is broken." << std::endl;
break;
}
}
message = GetMessageFromQueue( );
if ( !dataSocket.SendData( message ) )
{
break;
}
}
catch( std::exception &e )
{
std::cerr << "Connection is broken." << std::endl;
break;
}
}
dataSocket.Close( );
ServerDispatcher::Instance( ).DeleteClient( this );
}
void * ClientHandler::StartThread( void * arg )
{
reinterpret_cast<ClientHandler *>(arg)->run( );
}
#include "include/Socket.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cerrno>
#include <string>
#include <iostream>
Socket::Socket( )
{
}
Socket::~Socket( )
{
}
void Socket::Listen( const int port )
{
int yes = 1;
struct sockaddr_in address;
//Create socket and check if it worked
if ( (m_socketFD = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
{
std::cerr << "Error creating socket :: " << strerror( errno ) << std::endl;
return;
}
//Set socket to allow multiple connections
if ( setsockopt(m_socketFD, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0 )
{
std::cerr << "Error setting socket option :: " << strerror( errno ) << std::endl;
return;
}
address.sin_family = PF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( port );
//Bind socket to the specified port
if ( bind( m_socketFD, (struct sockaddr *)&address, sizeof( address )) < 0 )
{
std::cerr << "Error binding socket to port :: " << strerror( errno ) << std::endl;
return;
}
//Listen for connection calls
if ( listen( m_socketFD, 20 ) < 0 )
{
std::cerr << "Error listening for connections :: " << strerror( errno ) << std::endl;
return;
}
}
void Socket::Connect( const char *hostname, const int port )
{
struct sockaddr_in address;
//Create socket and check if it worked
if ( (m_socketFD = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
{
std::cerr << "Error creating socket :: " << strerror( errno ) << std::endl;
return;
}
address.sin_family = PF_INET;
address.sin_port = htons( port );
address.sin_addr.s_addr = inet_addr( hostname );
if ( connect( m_socketFD, (struct sockaddr *)&address, sizeof( address ) ) < 0 )
{
std::cerr << "Error connecting to server :: " << strerror( errno ) << std::endl;
return;
}
}
bool Socket::Accept( Socket& socket )
{
struct sockaddr_in address;
int FD;
socklen_t addrlen = sizeof( address );
//Accept incoming connections
FD = accept( m_socketFD, (struct sockaddr *)&address, &addrlen );
if ( FD < 0 )
{
std::cerr << "Error accepting connection :: " << strerror( errno ) << std::endl;
return false;
}
socket.SetSocketFD( FD );
return true;
}
void Socket::Close( )
{
//Close socket
if ( close( m_socketFD ) < 0 )
{
std::cerr << "Error closing socket :: " << strerror( errno ) << std::endl;
return;
}
}
bool Socket::SendData( std::string packedMessage )
{
const char *message = packedMessage.c_str( );
int nbytes;
//Send packed message to socket
nbytes = send( m_socketFD, message, sizeof( message ), 0 );
if ( nbytes == -1 )
{
std::cerr << "Error sending to socket :: " << strerror( errno ) << std::endl;
return false;
}
return true;
}
bool Socket::RecvData( char *buffer )
{
int nbytes;
//Get packed message from socket
nbytes = recv( m_socketFD, buffer, sizeof( buffer ), 0 );
if ( nbytes <= 0 )
{
if ( nbytes == 0 )
{
std::cerr << "Connection was closed." << std::endl;
return false;
}
else
{
std::cerr << "Error receiving from socket :: " << strerror( errno ) << std::endl;
return false;
}
}
return true;
}
int Socket::DataCheck( )
{
fd_set readfds;
int retval;
FD_ZERO( &readfds );
FD_SET( m_socketFD, &readfds );
retval = select ( m_socketFD + 1, &readfds, NULL, NULL, NULL );
return retval;
}
int Socket::GetSocketFD( )
{
return m_socketFD;
}
void Socket::SetSocketFD( int FD )
{
m_socketFD = FD;
}
bool Socket::SendData( std::string packedMessage, int msgSize )
{
const char *message = packedMessage.c_str( );
int nbytes;
//Send packed message to socket
nbytes = send( m_socketFD, message, msgSize, 0 );
if ( nbytes == -1 )
{
std::cerr << "Error sending to socket :: " << strerror( errno ) << std::endl;
return false;
}
return true;
}
bool Socket::RecvData( char *buffer, int bufferSize )
{
int nbytes;
//Get packed message from socket
nbytes = recv( m_socketFD, buffer, bufferSize, 0 );
if ( nbytes <= 0 )
{
if ( nbytes == 0 )
{
std::cerr << "Connection was closed." << std::endl;
return false;
}
else
{
std::cerr << "Error receiving from socket :: " << strerror( errno ) << std::endl;
return false;
}
}
return true;
}
Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.
Have a better answer? Share it in a comment.