Lesson11 图形的保存和重绘

1.    创建4个菜单,为其添加消息响应,用成员变量保存绘画类型。添加LButtonDownUp消息。

2.   当窗口重绘时,如果想再显示原先画的数据,则需要保存数据。为此创建一个新类来记录绘画类型和两个点。

class CGraph 

{

public:

CPoint m_ptOrigin;//起点

CPoint m_ptEnd;//终点

UINT m_nDrawType;//绘画类型

CGraph();

CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd);//此为构造函数。

virtual ~CGraph();

};

然后在void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)中加入如下代码

//CGraph graph(m_nDrawType,m_ptOrigin,point);//不能用局部变量

//m_ptrArray.Add(&graph);//加入这种指针数组中

/* OnPrepareDC(&dc);//这个函数中可以重新设置窗口原点,对于滚动条中,保存数据前要调用此函数

dc.DPtoLP(&m_ptOrigin);//将设备坐标转换为逻辑坐标

dc.DPtoLP(&point);//

CGraph *pGraph=new CGraph(m_nDrawType,m_ptOrigin,point);//在堆中创建新的对象

m_ptrArray.Add(pGraph);*///加入到指针数组中

GraphicView.h中有如下代码

CPtrArray m_ptrArray;

//OnDraw中重画时调出数据

for(int i=0;i<m_ptrArray.GetSize();i++)

3.    CView::OnPaint()调用了OnDraw(),但在void CGraphicView::OnPaint()MFCWizard没有调用OnDraw(),要注意这个区别。如果你此时想调用,必须手动添加代码。 OnDraw(&dc);

4.    让窗口具有滚动条的功能。

   1.CGraphicView的头文件中的CView全部替换成CSrollView

   2.添加如下的代码

void CGraphicView::OnInitialUpdate()

{

CScrollView::OnInitialUpdate();

 

// TOD Add your specialized code here and/or call the base class

SetScrollSizes(MM_TEXT,CSize(800,600));//设置映射模式,设定窗口大小。OK

}

5.    坐标系的转换,此处不再详细介绍,需要时请查阅相关资料。

6.    解决重绘时线跑到上面的问题。为什么会错位?因为逻辑坐标和设备坐标没有对应起来。解决方法:

OnLButtonDown画完图后,保存之前。调用

/* OnPrepareDC(&dc);//重新设置逻辑坐标的原点!!!

dc.DPtoLP(&m_ptOrigin);//设备坐标转化为逻辑坐标

dc.DPtoLP(&point);

CGraph *pGraph=new CGraph(m_nDrawType,m_ptOrigin,point);

m_ptrArray.Add(pGraph);*/

7.    另外两种方法来保存数据。一种是用CMetaFileDC,另一种是利用兼容DC,重绘时利用 pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcCompatible,0,0,SRCCOPY);将兼容DC的图拷贝到屏幕DC上去。

 

 

Lesson12 文件操作

1.       常量指针与指针常量的区分
 char ch[5]="lisi";
 const char *pStr=ch;//const*之前,表明指针指向的内容为常量,即为常量指针,但指针可指向其它变量。
 char * const pStr=ch;//const*之后,表明指针的地址不能改变,即为指针常量,但指针所指向的内容是可以改变的;

const char * const pStr = ch;指向常量的常量指针,指针的地址与指向的内容都不可以改变。

2.       对文件读写的三种方法

<1>.C语言

FILE *pFile=fopen("1.txt","w");//参数1文件路径,只写文件则在本工程中,参数2:打开模式

fwrite("http://www.sunxin.org",1,strlen("http://www.sunxin.org"),pFile);//写文件

原型:size_t fwrite(const void *buffer, size_t size, size_t count, FILE *stream);

在写完文件后要使用fflush(pFile);fclose(pFile)使数据写入到文件中,因为C语言对文

件的操作使用了缓冲文件系统,一般如果不手工刷新缓冲区的话,直到缓冲区满后才将数据写入到文件中

int fseek(FILE *stream, long offset, int origin);

stream 指向FILE结构体的指针

offset           设定偏移量

origin   指定文件指针的起始位置.( SEEK_SET开始处, SEEK_CUR文件当前位置处, SEEK_END文件的结尾处)

//fseek(pFile,0,SEEK_SET);

对于C语言文件操作来说 ,它有一个文件指针,该指针会随时根据我们对文件的操作来移动地,始终指向文件下一个写入的位置.当执行定稿操作之后,文件指针就指向了所写数据占据位置的下一个位置.如果希望在写入数据后,返回到文件的开始位置处再写入数据,就需要将这个文件指针移动到文件开始校园,这可以利用 fseek函数实现

//fwrite("ftp:",1,strlen("ftp:"),pFile);

//fwrite("http://www.sunxin.org",1,strlen("http://www.sunxin.org"),pFile);

char ch[100];接收文件中数据字符数据

memset(ch, 0, strlen(ch));

fread(ch, 1, 100, pFile);

fclose(pFile);*/关闭文件

//fflush(pFile);刷新缓冲区

<2>.C++

要包括头文件 "fstream.h"

/* ofstream ofs("4.txt");

ofs.write("http://www.sunxin.org",strlen("http://www.sunxin.org"));

ofs.close();*/

要注意的是:在读取文件时候ROF表示文件结尾,,readnext会将文件指针指向文件中下一个字符

<3<.MFC CFile

CFileDialog fileDlg(FALSE);

fileDlg.m_ofn.lpstrTitle="我的文件保存对话框";

fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";

fileDlg.m_ofn.lpstrDefExt="txt";

if(IDOK==fileDlg.DoModal())

{

 CFile file(fileDlg.GetFileName(),CFile::modeCreate | CFile::modeWrite);

 file.Write("http://www.sunxin.org",strlen("http://www.sunxin.org"));

 file.Close();

}

二进制文件和文本文件,实际上它们都是以二进制数据的方式存储的,文件只是计算机内在中以二进制表示的数据在外部存储介质上的另一种存放形式,对于文本文件来,它只是一种特殊形式的文件,它所存放的第一个字节都可以转换为一个可读的字符

注意:写入和读取文件操作的方式要一致,文本方式写入就用文本方式读取,二进制方式写入就用二进制方式读取.

面试题:给你一个整数,:98341,将这个整数保存到文件中,要求在以记事本程序打开该文件时,显示是:98341,<要注意字符与整型是通用的,在文件中字符也是以ASCII保存的)

FILE *pFile = fopen(“3.txt”, “w”);

char ch[5];

ch[0] = 9 + 48;

ch[1] = 8 + 48;

ch[2] = 3 + 48;

ch[3] = 4 + 48;

ch[4] = 1 + 48;//0对应的ASCII48,

fwrite(ch, 1, 5, pFile);//以这种方式写入,在记事本打开时就是98341

fclose(pFile);

4.利用win32 API函数 CreateFile(),WriteFile()

CreateFile函数将创建或打开下列对象,并返回一个用于读取该对象的句柄:

        文件, 管道, 邮槽(在线程通信时会用到), 通信资源, 磁盘设备, 控件台,目录(仅适用于打开操作)

Example:

void CLesson12View::OnFileWrite()

{

         // TODO: Add your command handler code here

         /*FILE *pFile = fopen("1.txt", "w");

         fwrite("C语言文件操作", 1, strlen("C语言文件操作"), pFile);

         fclose(pFile);

         */

         /*CFile file;

         file.Open("2.txt", CFile::modeCreate | CFile::modeWrite);

         file.Write("MFC文件操作", strlen("MFC文件操作"));

         file.Close();*/

 

         /*CFileDialog m_fileDlg(FALSE);

         m_fileDlg.m_ofn.lpstrDefExt = "txt";

         m_fileDlg.m_ofn.lpstrTitle ="保存我的文件";

         m_fileDlg.m_ofn.lpstrFilter = "Text File(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";

         if(IDOK == m_fileDlg.DoModal())

         {

                   CFile mFile;

                   mFile.Open(m_fileDlg.GetPathName(), CFile::modeCreate | CFile::modeWrite);

                   mFile.Write("test file write!", strlen("test file write!"));

                   mFile.Close();

         }*/

         //定义一个句柄变量

         HANDLE hFile;

         //创建文件

         hFile = CreateFile("5.txt", GENERIC_WRITE, 0,

                   NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);

         //接收实际写入的字节数据

         DWORD dwWrites;

         //写入数据

         WriteFile(hFile, "example", strlen("example"), &dwWrites, NULL);

         //关闭文件句柄

         CloseHandle(hFile);

}

 

4.注册表读写

 1.win.ini的读写

//::WriteProfileString("http://www.sunxin.org","admin","zhangsan");

/* CString str;

::GetProfileString("http://www.sunxin.org","admin","lisi",

 str.GetBuffer(100),100);

AfxMessageBox(str);*/

 2.注册表的读写

HKEY hKey;

DWORD dwAge=30;

RegCreateKey(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",&hKey);

RegSetValue(hKey,NULL,REG_SZ,"zhangsan",strlen("zhangsan"));

RegSetValueEx(hKey,"age",0,REG_DWORD,(CONST BYTE*)&dwAge,4);

RegCloseKey(hKey);以上是写入

Example:

void CLesson12View::OnRegWrite()

{

         // TODO: Add your command handler code here

         //注册表操作

         //RegCreateKey()

         //RegCloseKey()如果不需要以上找到注册表项

         HKEY mKey;

         DWORD dAge = 30;

         ::RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\www.sunxin.org\\admin", &mKey);

         ::RegSetValue(mKey, NULL, REG_SZ, "zhangsan", strlen("zhangsan"));

         ::RegSetValueEx(mKey, "age", 0, REG_DWORD, (CONST BYTE*)&dAge, 4);

         ::RegCloseKey(mKey);//在不使用的时候要调用这个函数

}

 

void CLesson12View::OnRegRead()

{

         // TODO: Add your command handler code here

         /*LONG lValue;

         RegQueryValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\www.sunxin.org\\admin", NULL, &lValue);

         char *ch = new char[lValue];

         RegQueryValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\www.sunxin.org\\admin", ch, &lValue);

         MessageBox(ch);*/

 

         HKEY hKey;

         ::RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\www.sunxin.org\\admin", &hKey);

         DWORD dwType;

         DWORD dwValue;

         DWORD dwAge;

         ::RegQueryValueEx(hKey, "age", 0, &dwType, (LPBYTE)&dwAge, &dwValue);

         CString str;

         str.Format("Age = %d", dwAge);

         MessageBox(str);

}

 

Lesson 13: 文档串行化

1.    CArchive在菜单打开保存时的代码

CFile file("1.txt",CFile::modeCreate | CFile::modeWrite);

CArchive ar(&file,CArchive::store);

int i=4;

char ch='a';

float f=1.3f;

CString str("http://www.sunxin.org");

ar<<i<<ch<<f<<str;以上是保存,打开略

2.    文档-视类结构简介

OnNewDocument在程序启动时被调用,此时可设置文档标题,也可以在String TableIDR_MAINFRAME的第二个"\"后改变文档的标题。须了解的7个字符串的用途,见PPT

   WinAPPInitInstance()中完成DOC,View,MainFrame的归一。

当点击系统的打开和新建菜单时,有一系列的步骤,孙鑫老师给我们跟踪了代码的调用过程,此段跟踪我们略过。但我们要牢记住:CWinAPP负责管理文档管理器,文档管理器有一个指针链表,且来保存文档模板的指针,文档模板指针管理三个类DOCVIEWMAINFRAME,使其为某文件对象服务。

3.    利用CArchive来保存一个类的对象,此类必须支持串行化,需要5个步骤。

 a.让类从CObject派生;

 b.覆盖Serialize()函数,在其中完成保存和读取功能;

 c..h中加入 DECLARE_SERIAL(CGraph)

    d.在。cpp中加入IMPLEMENT_SERIAL(CGraph, CObject, 1 )

 e.定义一个不带参数的构造函数。

保存绘画数据到文件的简单过程

 a.CGraph中增加一个画图的成员函数,其实不增加也行。可以在View中完成相应功能。

 b.增加四个画图菜单,菜单可以从11课的代码中拷贝。

 c.View中增加LButtonDownUP的响应,在UP中画图,在DOWN中保存点

 d.利用CObArray集合类来保存绘画数据

 e.CGraphicDOC::Serialize()中保存和读取数据

 f.然后在OnDraw中重绘。

4.           新建和打开文档时,要注意销毁原来的数据。在DOCDeleteContents虚函数中是好时机。代码如下

      

Example:

int nCount;

nCount=m_obArray.GetSize();

/*for(int i=0;i<nCount;i++)

{

 delete m_obArray.GetAt(i);//释放指针指向的内存空间

 //m_obArray.RemoveAt(i);//移除链表中的元素。但在此处不能这样用,会导致非法操作。要用下面的方法沙

}

m_obArray.RemoveAll();*/

while(nCount--)

{

 delete m_obArray.GetAt(nCount);

 m_obArray.RemoveAt(nCount);

}

 

 

Lesson14 网络编程

sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基于TCPsocket编程是采用的流式套接字(SOCK_STREAM)。基于UDP采用的数据报套接字(SOCK_DGRAM).

1.TCP流式套接字的编程步骤

在使用之前须链接库函数:工程->设置->Link->输入ws2_32.libOK

服务器端程序:

1、加载套接字库

2、创建套接字(socket)。

3、将套接字绑定到一个本地地址和端口上(bind)。

4、将套接字设为监听模式,准备接收客户请求(listen)。

5、等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。

6、用返回的套接字和客户端进行通信(send/recv)。

7、返回,等待另一客户请求。

8、关闭套接字。

客户端程序:

1、加载套接字库

2、创建套接字(socket)。

3、向服务器发出连接请求(connect)。

4、和服务器端进行通信(send/recv)。

5、关闭套接字。

 

(TCP)服务器端代码如下:

#include <winsock2.h>

#include <stdio.h>

void main()

{

         WORD wVersionRequested;//版本号

         WSADATA wsaData;

         int err;

         wVersionRequested = MAKEWORD(1, 1);//1.1版本的套接字

 

         err = WSAStartup(wVersionRequested, &wsaData);

         if (err != 0)

         {

                   return;

         }//加载套接字库,如果失败返回0

         if (LOBYTE(wsaData.wVersion) != 1 ||

                   HIBYTE(wsaData.wVersion) != 1)

         {

                   return;

         }//判断高低字节是不是1,如果不是1.1的版本则退出

 

         //创建流式套接字,基于TCP(SOCK_STREAM)

         SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);

         //Socket地址结构体的创建

         SOCKADDR_IN addrSrv;

         addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//转换Unsigned long型为网络字节序格式

         addrSrv.sin_family = AF_INET;//指定地址簇

         addrSrv.sin_port = htons(6000);

//指定端口号,sin_family参数外,其它参数都是网络字节序,因此需要转换

        

         //将套接字绑定到一个端口号和本地地址上

         bind(socSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

        

         listen(socSrv, 5);

         SOCKADDR_IN addrClient;//字义用来接收客户端Socket的结构体

         int len = sizeof(SOCKADDR);//初始化参数,这个参数必须进行初始化

 

         //循环等待接受客户端发送请求

         while (1)

         {

                   //等待客户请求到来;当请求到来后,接受连接请求,

                   //返回一个新的对应于此次连接的套接字(accept)。

                   //此时程序在此发生阻塞

                   SOCKET sockConn = accept(socSrv, (SOCKADDR*)&addrClient, &len);

 

                   char sendBuf[100];

                   sprintf(sendBuf, "Welcome %s to http://sunxin.org",

                            inet_ntoa(addrClient.sin_addr));//格式化输出

                   //用返回的套接字和客户端进行通信

                   send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多发送一个字节

 

                   //接收数据

                   char recvBuf[100];

                   recv(sockConn, recvBuf, 100, 0);

                   printf("%s\n", recvBuf);

                   closesocket(sockConn);

         }

}

 

(TCP)客户端代码如下:

#include <winsock2.h>

#include <stdio.h>

void main()

{

         WORD wVersionRequested;//版本号

         WSADATA wsaData;

         int err;

         wVersionRequested = MAKEWORD(1, 1);//1.1版本的套接字

        

         err = WSAStartup(wVersionRequested, &wsaData);

         if (err != 0)

         {

                   return;

         }//加载套接字库,如果失败返回0

         if (LOBYTE(wsaData.wVersion) != 1 ||

                   HIBYTE(wsaData.wVersion) != 1)

         {

                   return;

         }//判断高低字节是不是1,如果不是1.1的版本则退出 

         //创建流式套接字,基于TCP(SOCK_STREAM)

         SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);

         //Socket地址结构体的创建

         SOCKADDR_IN addrSrv;

         addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//转换字符型为网络字节序格式

         addrSrv.sin_family = AF_INET;//指定地址簇

         addrSrv.sin_port = htons(6000);

//指定端口号,sin_family参数外,其它参数都是网络字节序,因此需要转换

        

         connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

         char recvBuf[100];//和服务器端进行通信(send/recv)。

         recv(sockClient,recvBuf,100,0);

         printf("%s\n",recvBuf);

         send(sockClient,"This is lisi",strlen("This is lisi")+1,0);

        

         closesocket(sockClient);//关闭套接字。

         WSACleanup();//必须调用这个函数清除参数

}

 

2.UDP型套接字。

服务器端(接收端)程序:

1、创建套接字(socket)。

2、将套接字绑定到一个本地地址和端口上(bind)。

3、等待接收数据(recvfrom)。

4、关闭套接字。

客户端(发送端)程序:

1、创建套接字(socket)。

2、向服务器发送数据(sendto)。

3、关闭套接字。

(UDP)服务器端代码:

#include <winsock2.h>

#include <stdio.h>

 

//基于UDP开支套接字服务器程序

void main(){

         WORD wVersionRequested;

         WSADATA wsaData;

         int err;

        

         wVersionRequested = MAKEWORD( 1, 1 );

        

         err = WSAStartup( wVersionRequested, &wsaData );

         if ( err != 0 ) {

                   return;

         }

        

        

         if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 ) {

                   WSACleanup( );

                   return;

         }

        

         SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);//创建套字(socket)

         SOCKADDR_IN addSrv;

         addSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

         addSrv.sin_family = AF_INET;

         addSrv.sin_port = htons(6000);

         bind(sockSrv, (SOCKADDR*)&addSrv, sizeof(SOCKADDR));

        

         SOCKADDR_IN addrClient;

         int len = sizeof(SOCKADDR);

         char recvBuf[100];

 

         recvfrom(sockSrv, recvBuf, 100, 0,

                   (SOCKADDR*)&addrClient, &len);

         printf("%s\n", recvBuf);

         closesocket(sockSrv);

         WSACleanup();

        

}

(UDP)客户端代码:

#include <winsock2.h>

#include <stdio.h>

 

void main(){

         WORD wVersionRequested;

         WSADATA wsaData;

         int err;

        

         wVersionRequested = MAKEWORD( 1, 1 );

        

         err = WSAStartup( wVersionRequested, &wsaData );

         if ( err != 0 ) {

                   return;

         }

        

        

         if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 ) {

                   WSACleanup( );

                   return;

         }

        

         SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);

         SOCKADDR_IN addrSrv;

         addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

         addrSrv.sin_family = AF_INET;

         addrSrv.sin_port = htons(6000);

 

         sendto(sockClient, "Hello Server!", sizeof("Hello Server!") + 1,

                   0, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

         closesocket(sockClient);

         WSACleanup();

}

===========下面是字符界面下的一个简单UDP聊天程序=====

UDP聊天程序服务器端:==============================

#include <winsock2.h>

#include <stdio.h>

 

//=========基于UDP聊天程序=====

//服务器端

void main(){

         WORD wVersionRequested;

         WSADATA wsaData;

         int err;

        

         wVersionRequested = MAKEWORD( 1, 1 );

        

         err = WSAStartup( wVersionRequested, &wsaData );

         if ( err != 0 )

         {

                   return;

         }

         if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 )

         {

                   WSACleanup( );

                   return;

         }

        

         SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);

         SOCKADDR_IN addrSrv;

         addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

         addrSrv.sin_family = AF_INET;

         addrSrv.sin_port = htons(6000);

 

         bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

 

         char sendBuf[100];

         char recvBuf[100];

         char tempBuf[100];

 

         int len = sizeof(SOCKADDR);

 

         SOCKADDR_IN addrClient;

         while (1)

         {

                   recvfrom(sockSrv, tempBuf, sizeof(tempBuf), 0, (SOCKADDR*)&addrClient, &len);

                   if ('q' != tempBuf[0])

                   {

                            sprintf(recvBuf, "%s say: %s", inet_ntoa(addrClient.sin_addr), tempBuf);

                            printf("%s\n", recvBuf);

                            printf("please input your data:");

                            gets(sendBuf);

                            sendto(sockSrv, sendBuf, strlen(sendBuf) + 1,

                                     0, (SOCKADDR*)&addrClient, len);

                   }

                   else

                   {

                            printf("%s request to quit the chat platform", inet_ntoa(addrClient.sin_addr));

                            sendto(sockSrv, "q", strlen("q") + 1, 0, (SOCKADDR*)&addrClient, len);

                            break;

                   }

                  

         }

         closesocket(sockSrv);

         WSACleanup();

}

UDP聊天程序客户端:===============================

#include <WINSOCK2.H>

#include <stdio.h>

 

void main(){

         WORD wVersionRequested;

         WSADATA wsaData;

         int err;

        

         wVersionRequested = MAKEWORD( 1, 1 );

        

         err = WSAStartup( wVersionRequested, &wsaData );

         if ( err != 0 )

         {

                   return;

         }

         if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 )

         {

                  WSACleanup( );

                   return;

         }

        

         SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);

         SOCKADDR_IN addrSrv;

         addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

         addrSrv.sin_family = AF_INET;

         addrSrv.sin_port = htons(6000);

 

         char sendBuf[100];

         char tempBuf[100];

         char recvBuf[100];

 

         int len = sizeof(SOCKADDR);

         while(1){

                   printf("please input your data:\n");

                   gets(sendBuf);

                   sendto(sockClient, sendBuf, sizeof(sendBuf) + 1,

                            0, (SOCKADDR*)&addrSrv, len);

                   recvfrom(sockClient, tempBuf, 100, 0, (SOCKADDR*)&addrSrv, &len);

 

                   if ('q' != tempBuf[0])

                   {

                            sprintf(recvBuf, "%s say: %s", inet_ntoa(addrSrv.sin_addr), tempBuf);

                            printf("%s\n", recvBuf);

                   }

                   else{

                            printf("the server has been closed!\n");

                            sendto(sockClient, "q", strlen("q") + 1,

                                     0, (SOCKADDR*)&addrSrv, len);

                            break;

                   }

                  

         }

         closesocket(sockClient);

         WSACleanup();

}