[ Home | Syllabus | Course Notes | Assignments | Search]
What are the important design decisions?
Let's discuss each in term:
There are several choices:
bool client_GetHeadPosition(POSITION& position,CStudent& student); // return is true if the list in not empty, else false // returns position of head element and student in that position.
POSITION client_AddTail(const CStudent& student); // adds student to the end of the list // returns its position
CStudent contains a name of type CString. While CString is a very useful and powerful Object, it is difficult to marshall into a data packet since it can be a varying size. We will take the easy way out and marshall it as a fixed length character array. Let's assume that the student name is no more than 50 characters.
Here is the packet for the return values for client_GetHeadPosition (there is no need for input arguments)
typedef struct { // output parameters
NET_CONTROL status;
POSITION pos;
char stuName[50];
int stuGrade;
} PCKT_HEAD_OUT;
// And here is the stub function on the server
void server_GetHeadPosition(SOCKET socket2client)
{
PCKT_HEAD_OUT pcktOut;
pcktOut.pos = m_studentList.GetHeadPosition();
if(pcktOut.pos != NULL) {
CStudent* pStudent = m_studentList.GetAt(pcktOut.pos);
pcktOut.stuGrade = pStudent->m_nGrade;
strncpy(pcktOut.stuName, pStudent->m_strName.GetBuffer(50), 50);
} else {
pcktOut.stuGrade = 0;
pcktOut.stuName[0] = NULL;
}
pcktOut.status = SUCCESS;
if(!sendPacket(socket2client, LPBYTE(&pcktOut), sizeof (pcktOut))) {
closesocket(socket2client);
WSACleanup();
ExitProcess(1);
}
}
// And here is the proxy for the client
bool client_GetHeadPosition(POSITION& position,CStudent& student)
{
PCKT_HEAD_OUT pcktOut;
if (!sendControl(socket2server, HEAD))
return false;
if(!getPacket(socket2server, LPBYTE(&pcktOut), sizeof(pcktOut)))
return false;
if(pcktOut.status != SUCCESS)
return false;
position = pcktOut.pos;
student.m_strName = pcktOut.stuName; // overload assignment from character arrays
student.m_nGrade = pcktOut.stuGrade;
if(pcktOut.pos == NULL) return false;
else return true;
}
There are several choices for implementing a list on the server:
To demonstrat how to use MFC classes in a console mode program, we will use the first. There are several header files/libraries that need to be set:
#include <afxsock.h>
To prevent one user from deleting student record that another student is viewing, you need to keep track of which clients are viewing which record.
I suspect that the "position" of a Student record in the CObjList uniquely identifies that record.
Unless you are doing a team project, a client is only known by a socket connection to a dedicated thread. Maybe you could use the threadID or socket to uniquely identify the client's thread.