[ 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.