CSocket类是MFC对Windows Socket编程的类的封装,其派生于CAsyncSocket类,即是CAsyncSocket类的更抽象的封装,用该类来完成Socket编程将更方便。然而CAsyncSocket类使用起来更加灵活。因而在Socket编程中如果要获取看不同的需求而确定用不同的类。
只是在TCP(SOCK_STREAM)的编程中,CSokcet类还实现了防阻塞的功能。并且在CSocket类中实现了将没有接收到数据的recv函数挂起以执行另外一个接收函数的技术,以实现在一个服务器程序中实现多个客户端程序的连接。并且CSocket类配合CArchive类以及CSocketFile类可以方便的实现数据在服务器以及客户端的传输。
CSocket类的使用分以下5个步骤:
1. 声明Socket对象(或是从CSocket类派生出来的自己的对象)。调用Create函数创建。
2. 若是在服务器端,调用Listen函数用于设定一个可以接收客户端程序的端口号,并在后面响应OnAccept函数,用于客户定制的处理。当然在CSocket类中也可以不调用,这样系统自动调用缺省的函数,做一个空处理。
如是在客户端,则调用Connect函数,将客户机程序于特定服务器及端口号连接
3. 构造CSocketFile类对象,并在构造函数中关联CSocket类对象
4. 创建CArchive类的对象,在构造函数中将CSocketFile类的对象关联到这样的对象中,用于接收与发送数据。
5. 在通信结束有,将CSocket类,CArchive类,CSocketFile类的对象分别销毁。
下面是对该程序的解读:
总体的框架:
该程序总共创建了四个自定义的类,分别是CListenningSock类,派生于CSocket类,拥有成员变量,CServerDlg *m_pDlg,成员函数OnAccept。该类主要是一个服务器的连接套接字,用于在服务器端的一些设置功能。CMsg类,主要用于消息的接收以及将其串行化:他拥有的成员函数以及成员变量如下:Init, Serialize(CArchive& ar); CString m_strText; BOOL m_bClose; CStringList m_msgList; .以及CClientSock类,其主要是处理客户端发送过来的消息。他的成员函数以及成员变量有int m_nMsgCount, CSocketFile* m_pFile, CArchive* m_pArchiveIn, CArchive* m_pArchiveOut , CServerDlg* m_pDlg, IsAbouted(), Initialize(), SendMessage(), ReceiveMessage(), OnReceive();还有一个是端口号的设置对话框,他非常简单,就不用介绍了。再有就是对话框主窗口函数了,这些函数在调用过程中具体再介绍。
程序的运行脉络:
1.在程序的运行过程中,首先进入App类的初始化函数,在之中调用主对话框(CServerDlg)DoModal,启动对话框,在主对话框类中首先调用的是其OnInitialDialog函数,在其中调用在其中调用了设置端口号的对话框,并在设置后调用了Create及Listen函数,将服务器程序进入服务状态。
2.在Listen后,当有客户机程序的连接请求到来后,服务器程序自动调用CListenningSock类的OnAccept函数,这个函数调用了主框架窗口的OnAccept函数
在这个处理中,程序首先生成一个客户端套接字对象,并通过Accetp函数将其于服务器端关联起来,然后调用自身的Initialize函数将自己的对象初始化。
每一个客户机的连接都会先发送一个客户机进入的消息,而此消息将触发服务器端程序调用客户机的套接字类的OnReceive函数,而这个函数有调用了CServerDlg类的OnReceive函
数,在这个函数中,读取已收到的消息队列的内容,如果有是关闭的消息,则将该对象指针销毁。对象的销毁调用了DeleteSocket函数,他历遍所有的连接客户端对象,如有发现该客户机的套接字为关闭状态,则将其清楚,并重新显示界面上的信息。
读取消息过程是调用了CClientSock类中的ReceiveMessage函数,作用对消息串行化。
而消息的串行化是通过消息类自身的函数来实现的
在OnReceive函数中,最后掉用了UpdateClients函数,即是在服务器每次接收到消息后便要将消息数以及消息内容的显示更新。
在这个函数中,他历遍了所有以连接的客户机的CClientSock类的实例。先是收集消息,如果有新的消息生成,要更新消息队列。在收集消息的过程中,对新的消息做一个循环,将新的消息添加到消息队列中来。并更新CClientSoock类中消息的总数。将消息发给每一个客户程序。如果消息总数没有变化,则返回NULL值,表明不用更新窗口。
在后调用UpdateInfo函数将界面中的数据显示为新的饿数据
如果有新的消息进入,则需要更新显示,那么要调用SendMsg函数做为更新处理
在其中调用了CClientSock类的SendMessage函数,
经消息串行化,并强制写入“文件中”(CSocketFile类对象)
该过程成所有的就是这样了,其他的就是做一些扫尾工作了,除了OnDestroy重要一些,其他的都是没什么要紧的了。该函数完成了在服务器关闭后,想每一个客户机都发送一个服务器终止服务的消息,并断开所有的连接。
具体的程序代码在资源中可以找到