i really need a big help from you guys!!my codes for our midterm project is still not successful. today(9-19-09) was suppostedly last submission but luckily, our lab teacher moved it to next saturday, 9-26-09. the only thing i understand with this code is the general flow of the codes, i still cant understand the specific implementations. im still not good with the language used because im having a hard time studying it but i really wanna master in(c++). i wish you can help me make myself understand the codes and i also beg for your help to give a hint on how to solve this program.pls help to have a passing mark on this course.
problem
our 2nd project in my computer proggramming 2 class is to modify a chatting code and add the following
1. Take a look at the implementation of the .nick <nick> command in talker.cpp. Modify it so that the user can only change his/her current nick to <nick> only if <nick> is not used yet.
2. Modify talker.cpp chat server program to include the following commands:
* .talk <nick> <msg> - this command sends the message <msg> privately to user <nick>.
* .who - displays all currently logged in users.
* .emote <something> - displays <something> next to your nick. For example, if you type,
.emote feels sad.
will display,
<your nick> feels sad.
* .pokes <nick> - displays the following on the screen:
/*
NOTE: This is a basic chat server which allows users to connect to it and be able
to talk in a public chat room. To connect, enter the following at your DOS prompt:
telnet localhost 6789
Do this for each chat client. If you want your classmates to connect to your server
within the laboratory LAN, simply change the macro 'HOST' to the actual IP address
of your network interface. For example, if the IP address of your network interface
is 10.10.7.23, then he/she can connect to your server by entering,
telnet 10.10.7.23 6789
at his/her DOS prompt.
*/
#include <iostream>
#include "PassiveSocket.h" // Include header for passive socket object definition
#define HOST "127.0.0.1" // localhost
#define PORT 6789
#define VERSION 0.01
#define NAME_LEN 11 // including the null character
#define MAX_PACKET 163 // actual message is 160-char long + "\r\n\0"
#define MAX_CLIENTS 100
#define TIME_OUT 5 // in minutes
#define SERVER_FULL "The server is full at the moment. Try again later."
using namespace std;
void bcast(CActiveSocket **clients, int clientCount, char *data, int except);
void sendto(CActiveSocket *client, char *data);
char *new_nick(char names[MAX_CLIENTS][NAME_LEN], int clientCount);
int main()
{
// server socket
CPassiveSocket server;
// client sockets
CActiveSocket *clients[MAX_CLIENTS], *incoming;
// number of clients connected so far
int clientCount;
// nicknames of the connected clients
char names[MAX_CLIENTS][NAME_LEN];
// msg is the message received from client 'i' so far
char msg[MAX_CLIENTS][MAX_PACKET];
// time_of_last_send[i] stores the last time that the client 'i' has sent a message;
// this will be used to impose timeouts on idle clients
long int time_of_last_send[MAX_CLIENTS];
// temporary string variables
char tmpdata[MAX_PACKET+20];
char tmpnick[NAME_LEN];
// Initialize server socket
server.Initialize();
// necessary so our server won't block (i.e. pause and wait) for input
server.SetNonblocking();
// and make it listen at host HOST and port PORT
server.Listen((const uint8 *) HOST, PORT);
cout << "TALKER v" << VERSION << endl;
cout << "Address: " << HOST << " Port: " << PORT << endl;
// we have no clients so far
clientCount = 0;
cout << "Number of clients: " << clientCount << endl;
// while it's not the end of the world
while (1)
{
// accept an incoming connection
if ((incoming = server.Accept()) != NULL)
{
// see if we can accommodate one more client
if (clientCount < MAX_CLIENTS)
{
// take that incoming connection
clients[clientCount] = incoming;
// necessary so our client won't block (i.e. pause and wait) for input
clients[clientCount]->SetNonblocking();
// start with a default nick and
strcpy(names[clientCount], new_nick(names, clientCount));
// an empty message buffer
strcpy(msg[clientCount], "");
cout << names[clientCount] << " has joined." << endl;
// inform other clients
sprintf(tmpdata, "\n\r%s has joined.\n\r", names[clientCount]);
bcast(clients, clientCount+1, tmpdata, clientCount);
// we have one more client in
clientCount++;
cout << "Number of clients: " << clientCount << endl;
} // if
else // maximum number of clients reached; reject connection
{
incoming->Send((const uint8 *) SERVER_FULL, strlen(SERVER_FULL));
incoming->Close();
} // else
} // if
// for each client, check if it is sending a message to the server
// concatenate the new message of the client with its previous message if there's any
for (int i=0; i < clientCount; i++)
if (clients[i]->Receive(MAX_PACKET) > 0)
{
// empty tmpdata
strcpy(tmpdata, "");
// now catenate 'tmpdata' with the new message
strncat(tmpdata, (const char *) clients[i]->GetData(), clients[i]->GetBytesReceived());
// and then append it to the previous;
// msg[i] is the message received from client 'i' so far
strcat(msg[i], tmpdata);
}
// now, process the message sent by each client
// we only process a message if it is terminated by "\r\n" (produced by pressing the ENTER key)
// else we accumulate the messages above until it is terminated by "\r\n"
for (int i = 0; i < clientCount; i++)
{
// if the message contains '\n', process it
if (strchr(msg[i],'\n')) {
// but remove first "\r\n" from msg[i] by putting a '\0' before them
msg[i][strlen(msg[i])-2] = '\0';
// see if msg[i] is not empty
if (strlen(msg[i]) > 0)
{
// do the actual processing of the message here:
// any msg[i] which starts with a '.' is considered to be a command
if (msg[i][0] != '.')
{
// output to server console
cout << names[i] << ": " << msg[i] << endl;
// broadcast to the clients
sprintf(tmpdata, "%s: %s\n\r", names[i], msg[i]);
bcast(clients, clientCount, tmpdata, -1);
} else // it's a command!
{
// .nick <nickname> - change nickname command
if (strncmp(msg[i], ".nick ", 6) == 0)
{
// copy new nick which is right after the space after .nick
strcpy(tmpnick, msg[i]+6);
cout << names[i] << " is now known as " << tmpnick << "." << endl;
// broadcast to all the rest of the clients,
sprintf(tmpdata, "\n\r%s is now known as %s.\n\r", names[i], tmpnick);
bcast(clients, clientCount, tmpdata, i);
// now, overwrite the old nick with the new one
strcpy(names[i], tmpnick);
}
else if (strncmp(msg[i], ".quit", 5) == 0)
{
// say 'Bye.' to disconnecting client
sendto(clients[i], "Bye.");
// and then inform the others
sprintf(tmpdata, "\n\r%s is now offline.\n\r", names[i]);
bcast(clients, clientCount, tmpdata, i);
// and finally, close the connection
clients[i]->Close();
// DELETION OF THE CLIENT FROM THE LIST:
// now, we move all storage starting at client 'i+1'
// to client 'clientCount-1', overwriting client 'i'
for (int j = i; j < clientCount-1; j++)
{
clients[j] = clients[j+1];
strcpy(msg[j], msg[j+1]);
strcpy(names[j], names[j+1]);
}
// less one client
clientCount--;
cout << "Number of clients: " << clientCount << endl;
// finally, restart 'i' to the position where we
// performed the deletion to process the client
// we moved from 'i+1'
i--;
// bypass post processing of 'msg[i]' and
// the display of the '>' prompt below
goto after_deletion;
}
}
}
// after processing the message buffer, empty it!
strcpy(msg[i], "");
// and then display the prompt '>'
sprintf(tmpdata, "%s> ", names[i]);
clients[i]->Send((const uint8*) tmpdata, strlen(tmpdata));
after_deletion:;
} // if
} // for
} // while
// close server socket
server.Close();
return 0;
} // main
// broadcasts 'data' to all clients except 'except'.
// to include sender, call this function with 'except' set to -1.
void bcast(CActiveSocket **clients, int clientCount, char *data, int except)
{
for (int i = 0; i < clientCount; i++)
if (i != except)
clients[i]->Send((const uint8*) data, strlen(data));
}
char *new_nick(char names[MAX_CLIENTS][NAME_LEN], int clientCount)
{
char tmpnick1[NAME_LEN], tmpnick2[NAME_LEN];
int unique_nick;
char msg[MAX_CLIENTS][MAX_PACKET];
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (strcpy(tmpnick1, "Guest"))
{
itoa(i, tmpnick2, MAX_CLIENTS);
strcat(tmpnick1, tmpnick2);
unique_nick = 1;
for (int j = 0; j < clientCount; j++)
if (strcmp(tmpnick1, names[j]) == 0)
unique_nick = 0;
if (unique_nick)
return tmpnick1;
else if (strncmp(msg[i], ".who", 4) == 0)
{
//displays all the login users
cout << "This is the list of online users:" << endl;
for (int j=0; j < clientCount; j++)
{
cout << names[j] <<endl;
}
}
You may want to add code tags to your code (hash button on the right of the text box when editing your post).
If you understand most of the code, can't you just say to your teacher, "Hey, I don't understand this part."? He's there to help, isn't he?
Also, read through it, and make note of the parts you don't understand. You have to understand part of it, no? When your done, you should have a list of things that you need help on, which should help you to ask more specific questions and to ask your instructor questions.
Remember, nobody can help if you don't tell us what part of the implementation you don't understand.
EDIT: Also, shouldn't this be in some other section? Maybe "General C++ Programming"?
my confusions with this code is about 75%
can you help me on what specific tutorial i need to study in order for me to answer my confusions
pls
I would be glad to help, but I don't know what your confusions are.
If you really can't explain what you don't understand, just go through the tutorials (http://cplusplus.com/doc/tutorial/) on this site. Skip over the ones you understand, and read the ones you don't. I can't really direct you anywhere if I don't know what you don't understand.
ive read many c tutorials but they are not like that. i mean, they are using different implementation of c
I assume you mean C++, not C; they're completely different things. If you've been reading C tutorials, you've been learning the wrong thing. The tutorials here are for standard C++, so you should be able to apply them to understanding your instant messenger code.
what i really dont understand is the implementation of the codes
what every single word mean
what codes are used and why are they used
So you're saying that you don't understand:
1. the preprocessor
2. functions
3. function prototypes
4. classes
5. variables
6. arrays
7. pointers
If you said yes to any of those, you need to go through some basic C++ tutorials, such as the ones on this site. There is a table of contents for the tutorials, so you can skip to the ones you are having trouble understanding.
If you understand those, you should look at the reference section (http://cplusplus.com/reference/), specifically cstdlib, cstdio & iostream. Those cover many of the functions that the code uses. (Which is strange, since it doesn't seem to have #included those. Does it even compile?)