vc++网络程序设计实例

上传人:小*** 文档编号:243077782 上传时间:2024-09-15 格式:PPT 页数:200 大小:749.50KB
返回 下载 相关 举报
vc++网络程序设计实例_第1页
第1页 / 共200页
vc++网络程序设计实例_第2页
第2页 / 共200页
vc++网络程序设计实例_第3页
第3页 / 共200页
点击查看更多>>
资源描述
,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,网络程序设计实例,网络程序设计实例,.1,使用,Winsock API,设计网络程序的实例,.2,使用,MFC,类库进行网络程序设计的实例,.3,基于,WinInet,API,的客户程序编写实例,.4,原始套接口,(SOCK_RAW),程序设计实例,.5,广播通信与组播通信程序设计实例,习题,.1,使用,Winsock API,设计网络程序的实例,.1.1,程序源代码,1,UDP,程序,1,的源代码,/,编程环境:,VC 6.0,/,程序说明:基于用户数据报协议,UDP,的程序实例,/,程序功能:在窗口中点击鼠标左键,则发送信息到端口号为,6000,的远程机上,并可以从端,/,口号,6000,的远程机接收数据,#include ,stdafx.h,#include ,/,/,说明全局量,HINSTANCE,hInst,;,LRESULT CALLBACK,WndProc(HWND, UINT, WPARAM, LPARAM);,/,int,APIENTRY,WinMain(HINSTANCE,hI,HINSTANCE,hP,LPSTR,lp,int,nC,),MSG,msg,;,HWND,hWnd,;,/,实例句柄存入全局量,hInst,hInst,=,hI,;,WNDCLASS,wc,;,memset(,wc.lpfnWndProc,= (,WNDPROC)WndProc,;,wc.hInstance,=,hI,;,wc.hIcon,=,LoadIcon(NULL, IDI_APPLICATION);,wc.hbrBackground,= (HBRUSH)COLOR_WINDOW;,wc.lpszClassName,= W1;,RegisterClass(&wc,);,hWnd,=CreateWindowEx(WS_EX_PALETTEWINDOW,W1,UDP,程序,1,端口,:8000,WS_OVERLAPPEDWINDOW,100,100,200,100,NULL, NULL,hI, NULL);,if (!,hWnd,),return FALSE;,ShowWindow(hWnd,nC,);,/,主消息循环,while (,GetMessage(&msg, NULL, 0, 0),TranslateMessage(&msg,);,DispatchMessage(&msg,);,return,msg.wParam,;,/,/,定义,Winsock API,需要的量,WSADATA,ws,;,SOCKET s1,s2;,struct,sockaddr_in,Cs1A,Cs2A;,/,发送数据缓冲,char sendBuf200;,/,接收数据缓冲,char recvBuf200;,int,len,;/,存放接收到的字节数,#define Cs1Port 8000/,本地端口号,#define Cs2Port 6000/,远程端口号,#define Cs1IP 127.0.0.1/,本地,IP,地址,#define Cs2IP 127.0.0.1/,远程,IP,地址,/,/,消息处理,LRESULT CALLBACK,WndProc(HWND,hW, UINT,msg, WPARAM,wP, LPARAM,lP,),switch (,msg,),case WM_DESTROY:/,关闭程序触发事件,/,向,Windows,注销,Socket,触发事件,WSAAsyncSelect(s1,hW, 0, 0);,/,释放连接,closesocket(s1);,/,卸载动态链接库,Winsock DLL,WSACleanup,( );,PostQuitMessage(0);,break;,case WM_CREATE:/,初始化触发事件,/,装载动态链接库,Winsock DLL,WSAStartup(0x0202, &,ws,);,/,创建,UDP,套接字,s1=socket(AF_INET, SOCK_DGRAM,0);,/,设置地址类型,Cs1A.sin_family=AF_INET;,/,本地端口,Cs1A.sin_port = htons(Cs1Port);,/,本地,IP,地址,Cs1A.sin_addr.s_addr =inet_addr(Cs1IP);,/,进行本地绑定,len,=bind(s1,(struct,sockaddr,*) ,/,远程地址类型,Cs2A.sin_family=AF_INET;,/,远程端口,Cs2A.sin_port = htons(Cs2Port);,/,远程,IP,地址,Cs2A.sin_addr.s_addr =inet_addr(Cs2IP);,/,向,Windows,注册网络事件,WSAAsyncSelect(s1,hW,WM_USER+1,FD_READ);,Beep(2000,200);/,发出报警声音,break;,case WM_USER+1:/Socket,触发事件,switch(LOWORD(lP,),case FD_READ:/,接收远程信息,len,=recv(s1,recvBuf,sizeof(recvBuf),0);,recvBuflen,=0;,MessageBox(0,recvBuf,UDP,程序,1,从,UDP,程序,2,收到的数据,MB_OK);,break;,break;,case WM_LBUTTONDOWN:/,点击鼠标左键,/,将发送数据放入缓冲区,wsprintf(sendBuf,Hello,UDP,程序,2!);,len,= sizeof(Cs2A);,/,发送信息,sendto(s1,sendBuf,strlen(sendBuf),0,(struct,sockaddr,*) ,break;,return,DefWindowProc(hW,msg,wP,lP,);,2,UDP,程序,2,的源代码,/,编程环境:,VC 6.0,/,程序说明:基于用户数据报协议,UDP,的程序实例,/,程序功能:在窗口里点击鼠标左键,则发送信息到端口为,8000,的远程机上,并可以从端口,/,为,8000,的远程机接收数据,#include ,stdafx.h,#include ,/,/,说明全局量,HINSTANCE,hInst,;,LRESULT CALLBACK,WndProc(HWND, UINT, WPARAM, LPARAM);,/-,int,APIENTRY,WinMain(HINSTANCE,hI,HINSTANCE,hP,LPSTR,lp,int,nC,),MSG,msg,;,HWND,hWnd,;,/,实例句柄存入全局量,hInst,hInst,=,hI,;,WNDCLASS,wc,;,memset(,wc.lpfnWndProc,= (,WNDPROC)WndProc,;,wc.hInstance,=,hI,;,wc.hIcon,=,LoadIcon(NULL, IDI_APPLICATION);,wc.hbrBackground,= (HBRUSH)COLOR_WINDOW;,wc.lpszClassName,= W1;,RegisterClass(&wc,);,hWnd,=CreateWindowEx(WS_EX_PALETTEWINDOW,W1,UDP,程序,2,端口,:6000,WS_OVERLAPPEDWINDOW,400,200,200,100,NULL, NULL,hI, NULL);,if (!,hWnd,),return FALSE;,ShowWindow(hWnd,nC,);,/,主消息循环,while (,GetMessage(&msg, NULL, 0, 0),TranslateMessage(&msg,);,DispatchMessage(&msg,);,return,msg.wParam,;,/,/,定义,Winsock API,需要的量,WSADATA,ws,;,SOCKET s1,s2;,struct,sockaddr_in,Cs1A,Cs2A;,/,发送数据缓冲,char sendBuf200;,/,接收数据缓冲,char recvBuf200;,int,len,;/,存放接收到的字节数,#define Cs1Port 6000/,本地端口,#define Cs2Port 8000/,远程端口,#define Cs1IP 127.0.0.1/,本地网址,#define Cs2IP 127.0.0.1/,远程网址,/-,/,消息处理,LRESULT CALLBACK,WndProc(HWND,hW, UINT,msg, WPARAM,wP, LPARAM,lP,),switch (,msg,),case WM_DESTROY:/,关闭程序触发事件,/,向,Windows,注销,Socket,触发事件,WSAAsyncSelect(s1,hW, 0, 0);,/,释放连接,closesocket(s1);,/,卸载动态链接库,Winsock DLL,WSACleanup,( );,PostQuitMessage(0);,break;,case WM_CREATE:/,程序初始化触发事件,/,装载动态链接库,Winsock DLL,WSAStartup(0x0202,/,创建,UDP,套接字,s1=socket(AF_INET, SOCK_DGRAM,0);,/,设置地址类型,Cs1A.sin_family=AF_INET;,/,本地端口,Cs1A.sin_port = htons(Cs1Port);,/,本地,IP,地址,Cs1A.sin_addr.s_addr =inet_addr(Cs1IP);,/,进行本地绑定,len,=bind(s1,(struct,sockaddr,*) ,/,远程地址类型,Cs2A.sin_family=AF_INET;,/,远程端口,Cs2A.sin_port = htons(Cs2Port);,/,远程,IP,地址,Cs2A.sin_addr.s_addr =inet_addr(Cs2IP);,/,向,Windows,注册网络事件,WSAAsyncSelect(s1,hW,WM_USER+1,FD_READ);,break;,case WM_USER+1:/Socket,触发事件,switch(LOWORD(lP,),case FD_READ:/,接收远程信息,len,=recv(s1,recvBuf,sizeof(recvBuf),0);,recvBuflen,=0;,MessageBox(0,recvBuf,UDP,程序,2,从,UDP,程序,1,收到的数据,0);,break;,break;,case WM_LBUTTONDOWN:/,点击鼠标左键,wsprintf(sendBuf,Hello,UDP,程序,1!);,len,= sizeof(Cs2A);,/,发送信息,sendto(s1,sendBuf,strlen(sendBuf),0,(struct,sockaddr,*) ,break;,return,DefWindowProc(hW,msg,wP,lP,);,1.2,程序运行结果,在这两个程序调试、编译和链接正确后,就可以执行这两个程序了。这两个程序执行后的窗口如图,10-1,所示,其中,图,(a),是,UDP,程序,1,执行后的窗口,图,(b),是,UDP,程序,2,执行后的窗口。,(a) UDP,程序,1,的窗口,(b) UDP,程序,2,的窗口,图,10-1,UDP,程序执行后的窗口,程序执行后就可以检查它们所实现的功能了。在,UDP,程序,1,的窗口中点击鼠标左键,则可以发送数据给,UDP,程序,2,,,UDP,程序,2,在收到,UDP,程序,1,发送的数据后,弹出如图,10-2(a),所示的窗口,并显示收到的数据。同样,如果在,UDP,程序,2,的窗口中点击鼠标左键,则可以发送数据给,UDP,程序,1,,,UDP,程序,1,在收到,UDP,程序,2,发送的数据后,弹出如图,10-2(b),所示的窗口。,(a) UDP,程序,2,收到的信息,(b) UDP,程序,1,收到的信息,图,10-2,UDP,程序收到数据后弹出的窗口,在学习这两个程序的过程中,我们应该注意两个问题:,(1),在程序中,虽然使用的是数据报传输方式,(SOCK_DGRAM),,,但却使用,bind(),函数进行了地址的绑定。,(2),这两个程序的功能是一样的,所以代码几乎是相同的。,.2,使用,MFC,类库进行网络程序设计的实例,.2.1,创建客户端程序,我们使用,VC+,提供的可视化集成编程环境来创建客户端程序。创建客户端程序的主要步骤介绍如下。,1,创建一个工程,使用,VC+,的应用程序生成向导,(MFC AppWizardexe),创建一个基于对话框的工程,该工程的名称为,CSockClient,。,2,设计程序对话框,如图,10-3,所示。,图,10-3,添加类变量,3,生成,CAsyncSocket,类的子类,MySock,4,在,MySock.ccp,文件中添加文件包含信息,在生成的,MySock.cpp,中添加如下文件包含信息:,#include ,CSockClient.h,#include ,CSockClientDlg.h,“,5,向,MySock.h,文件中添加代码,向,MySock.h,文件中添加如下代码:,public:,BOOL,m_bConnected,; /,是否连接,UINT,m_nLength,; /,消息长度,char m_szBuffer4096; /,消息缓冲区,6,重载,MySock.ccp,文件中的各函数,(1),MySock,(),函数重载的代码如下:,MySock:MySock,(),m_nLength,=0;,memset(m_szBuffer,0,sizeof(m_szBuffer);,m_bConnected,=FALSE,MySock:MySock,(),/,关闭套接字,if(m_hSocket,!=INVALID_SOCKET),Close();,(2),OnReceive,(),函数重载的代码如下:,void,MySock:OnReceive(int,nErrorCode,),m_nLength,=Receive(m_szBuffer,sizeof(m_szBuffer),0);,/,下面两行代码用来获取对话框指针,CCSockClientApp,*,pApp,=(,CCSockClientApp,*),AfxGetApp,();,CCSockClientDlg,*,pDlg,=(,CCSockClientDlg,*),pApp,-,m_pMainWnd,;,pDlg,-m_MSGS.InsertString(0,m_szBuffer);,memset(m_szBuffer,0,sizeof(m_szBuffer);,CAsyncSocket:OnReceive(nErrorCode,);,(3),OnSend,(),函数重载的代码如下:,void,MySock:OnSend(int,nErrorCode,),Send(m_szBuffer,m_nLength,0);,m_nLength,=0;,memset(m_szBuffer,0,sizeof(m_szBuffer);,/,继续提请一个,读,的网络事件,接收,Server,消息,AsyncSelect(FD_READ,);,CAsyncSocket:OnSend(nErrorCode,);,(4),OnConnect,(),函数重载的代码如下:,void,MySock:OnConnect(int,nErrorCode,),if (,nErrorCode,=0),m_bConnected,=TRUE;,CCSockClientApp,*,pApp,=(,CCSockClientApp,*),AfxGetApp,();,CCSockClientDlg,*,pDlg,=(,CCSockClientDlg,*),pApp,-,m_pMainWnd,;,memcpy(m_szBuffer,Connected,to ,13);,strncat(m_szBuffer,pDlg,-,m_szServerAdr,sizeof(pDlg,-,m_szServerAdr,);,pDlg,-m_MSGS.InsertString(0,m_szBuffer);,/,提请一个,读,的网络事件,准备接收,AsyncSelect(FD_READ,);,CAsyncSocket:OnConnect(nErrorCode,);,7,新建一个输入地址的对话框,新建一个输入地址信息的对话框,IDD_Addr,用来输入,IP,地址和端口号;生成一个新的基于对话框的类,CAddrDlg,。,在该对话框中增加两个编辑,(Edit),控件:一个为,IDC_Addr,,,用来输入要连接的,IP,地址;另一个为,IDC_Port,,,用来输入端口号。,使用类向导,(,ClassWizard,),为,CAddrDlg,类添加,m_Addr,和,m_Port,两个类变量。它们的,ID,标识、类型和名称如下:,Control IDTypeMember,IDC_Addr,CString,m_Addr,IDC_Port,Int,m_Port,然后向,CSockClientDlg,类中添加如下代码:,protected:,int,TryCount,;,MySock,m_clientSocket,;,UINT,m_szPort,;,public:,char m_szServerAdr256;,10,添加“连接”按钮的程序代码,双击,IDD_CSOCKCLIENT_DIALOG,对话框中的“连接”按钮,添加以下代码:,void,CCSockClientDlg:OnConnect,(),m_clientSocket.ShutDown(2);,m_clientSocket.m_hSocket,=INVALID_SOCKET;,m_clientSocket.m_bConnected,=FALSE;,CAddrDlg,m_Dlg,;,/,默认端口,7,m_Dlg.m_Port,=7;,if (,m_Dlg.DoModal,()=IDOK & !,m_Dlg.m_Addr.IsEmpty,(),memcpy(m_szServerAdr,m_Dlg.m_Addr,sizeof(m_szServerAdr,);,m_szPort,=,m_Dlg.m_Port,;,/,建立计时器,每,1,秒尝试连接一次,直到连上或,TryCount,10,SetTimer(1,1000,NULL);,TryCount,=0;,11,添加,Windows,消息,WM_TIMER,的响应函数,OnTimer,void,CCSockClientDlg:OnTimer(UINT,nIDEvent,),if (,m_clientSocket.m_hSocket,=INVALID_SOCKET),BOOL,bFlag,=m_clientSocket.Create(0,SOCK_STREAM,FD_CONNECT);,if(!bFlag,),AfxMessageBox(Socket,Error!);,m_clientSocket.Close,();,PostQuitMessage(0);,return;,m_clientSocket.Connect(m_szServerAdr,m_szPort,);,TryCount,+;,if (,TryCount,=10 |,m_clientSocket.m_bConnected,),KillTimer(1);,if (,TryCount,=10),AfxMessageBox(Connect,Failed!);,return;,CDialog:OnTimer(nIDEvent,);,12,添加“发送”按钮的程序代码,双击,IDD_CSOCKCLIENT_DIALOG,对话框中的“发送”按钮,添加以下代码:,void,CCSockClientDlg:OnSend,(),if (,m_clientSocket.m_bConnected,),m_clientSocket.m_nLength,=,m_MSG.GetWindowText,(,m_clientSocket.m_szBuffer,sizeof(m_clientSocket.m_szBuffer,);,m_clientSocket.AsyncSelect(FD_WRITE,);,m_MSG.SetWindowText,();,13,添加“关闭”按钮的程序代码,双击,IDD_CSOCKCLIENT_DIALOG,对话框中的“关闭”按钮,添加以下代码:,void,CCSockClientDlg:OnExit,(),/,关闭,Socket,m_clientSocket.ShutDown(2);,/,关闭对话框,EndDialog(0);,上述步骤完成后,调试程序并建立可执行的,.EXE,文件。当该项目运行时,弹出如图,10-4,所示的程序对话框。点击“,Connect”,按钮,弹出如图,10-5,所示的对话框,输入要连接的服务器的,IP,地址和端口号,然后单击“,OK”,按钮。当连接建立后,就可以在客户程序对话框中输入回送信息,并按“,Send”,按钮进行程序测试了。,图,10-4,客户程序对话框,图,10-5,地址信息输入对话框,.2.2,创建服务器端程序,1,建立一个,CAsyncSocket,的子类,在本例中,由于我们要实现的是一个回声程序,所以服务器程序应将收到的信息原封不动地发送给客户程序。因此,服务器程序的代码主要是重载,CAsyncSocket,类的接收和发送函数。,建立一个,CAsyncSocket,类的子类,CNewSocket,,,并重载,CAsyncSocket,类的,OnReceive,(),和,OnSend,(),函数。程序代码如下:,CnewSocket:OnReceive(int,nErrorCode,),m_nLength,=,receive(m_szBuffer,sizeof(m_szBuffer,),0),;,/,直接转发消息,AsyncSelect(FD_WRITE,),;,CNewSocket:OnSend(int,nErrorCode,),send(m_szBuffer,,,m_nLength,,,0),;,2,创建一个用于建立连接的类,CMyServerSocket,创建一个用于建立连接的类,CMyServerSocket,,,并重载,CAsyncSocket,类的,OnAccept,(),函数。,在,MyServerSocket.h,中声明如下变量:,public,:,CNewSocket,*,m_pSocket,;,OnAccept,(),程序的代码如下:,void,CMyServerSocket,:,OnAccept(int,nErrorCode,),/,侦听到连接请求,调用,Accept,函数,CNewSocket,*,pSocket,= new,CNewSocket,(),;,if(Accept(*,pSocket,),pSocket,-,AsyncSelect(FD_READ,),;,m_pSocket,=,pSocket,;,else,delete,pSocket,;,3,为对话框添加一个“侦听”按钮,为对话框添加一个“侦听”按钮,并添加如下代码。,在,CSockServerDlg.ccp,中声明变量:,public,:,CMyServerSocket,m_srvrSocket,;,OnListen,(),函数的代码如下:,void,CCSockServerDlg,:,OnListen,(),if(m_srvrSocket.m_hSocket,=INVALID_SOCKET),BOOL,bFlag,=,m_srvrSocket.Create,(,UserPort,,,SOCK_STREAM,,,FD_ACCEPT),;,if(!bFlag,),AfxMessageBox(Socket,Error!),;,M_srvrSocket.Close,(),;,PostQuitMessage(0),;,Return,;,/,侦听,成功,等待连接请求,if(!m_srvrSocket.Listen(1),int,nErrorCode,=,m_srvrSocket.GetLastError,(),;,if (,nError,!=WSAEWOULDBLOCK),AfxMessageBox(Socket,Error!),;,M_srvrSocket.Close,(),;,PostQuitMessage(0),;,Return,;,.3,基于,WinInet,API,的客户程序编写实例,.3.1,应用程序说明,编程环境:,VC+ 6.0,。,程序功能:给定,Internet,中一台服务器的域名,客户机首先与该域名的服务器建立连接,然后查询该服务器提供的功能。当然用户也可以随便输入一个域名,看是否在,Internet,中有该域名的服务器。,.3.2,建立应用程序的用户操作界面,编写该程序要求用户对,VC,的编程环境比较熟悉。在该程序中我们建立一个基于对话框的用户界面。,1,使用,AppWizard,生成对话框程序框架,(1),在,VC,启动后,从“文件”菜单中选择“新建,”,,在“新建”对话框中选择使用,MFC,的应用程序生成向导建立一个应用程序,即选择“,MFC AppWizard(exe)”,,,然后在“工程”框内输入要新建工程的名称,在该例中我们取名为,scan,,,再单击“确定”按钮,如图,10-6,所示。,图,10-6,创建一个,WinInet,应用程序,(2),在弹出的“,MFC AppWizard-step 1”,对话框中,选择基于对话框的,(Dialog Based),应用程序类型,然后单击“下一步”按钮。,(3),在弹出的“,MFC AppWizard-step 2 of 4”,对话框中,取消,ActiveX Controls,控件的选中标记,并且注意不要选择“,Windows Sockets”,,,因为在该程序中我们不直接调用,Windows Sockets,函数;在对话框标题栏中输入“服务器功能扫描程序”,再单击“下一步”按钮。,(4),在弹出的“,MFC AppWizard-step 3 of 4”,对话框中,选择,MFC,所使用的链接库,一般选择静态链接库,再单击“下一步”按钮。,(5),在“,MFC AppWizard-step 4 of 4”,对话框中,一般不需要改变,MFC,AppWiard,自动生成的各种类名,直接按“完成”按钮即可,这时弹出一个新建的有关工程和信息的对话框。,2,编程对话框,(1),添加一个显示输出结果的编辑框。使用,VC,的资源工具给对话框添加一个编辑框,然后右击编辑框,在弹出的下拉菜单中选择“,Properties,”,,,在弹出的编辑控件属性对话框中,将资源的,ID,标识符设置为,IDC_EDIT1,,,再给该编辑框增加一些其他类型属性。如在“,Styles,”,选项卡中,选中图,10-7,所示的“,Mutiline,”,等属性。,图,10-7,属性对话框,(2),添加一个输入网址的编辑框。用与上面类似的方法再增加另一个编辑框,编辑框的,ID,标志设为,IDC_EDIT2,,,然后在属性对话框中选择“,Mutiline,”,和“,Want return”,属性。,(3),添加查询命令按钮。在对话框上的恰当位置添加,5,个按钮,这,5,个按钮分别用来实现,HTTP,、,FTP,、,Gopher,、,FINGER,和,WHOIS,查询功能,它们的,ID,标志分别设置为,IDC_BUTTON_HTTP,、,IDC_BUTTON_FTP,、,IDC_BUTTON_GOPHER,、,IDC_BUTTON_,FINGER,和,IDC_BUTTON_WHOIS,。,在上面的操作完成以后,适当调整这些资源的布局,使用户界面比较美观。最后的结果如图,10-8,所示。,图,10-8,应用程序对话框,.3.3,应用程序代码及其说明,1,给编辑框添加变量,为了完成程序的显示和输入功能,需要给编辑框添加对应的变量。为了简单起见,我们可以使用“,ClassWizard,”,给编辑框添加变量。编辑框,IDC_EDIT1,附加的变量为,m_out,,,编辑框,IDC_EDIT2,附加的变量为,m_host,,,它们都应为,CString,类型的变量。,2,HTTP,协议查询代码,给对话框类,CScanDlg,添加一个函数,用于实现,HTTP,查询。函数原形为:,void,TryURL(CString,URL);,其实现代码为:,void,CScanDlg:TryURL(CString,URL),CInternetSession,session;,m_out+=,正在链接,+URL+rn;,UpdateData(FALSE,);,CInternetFile,* file=NULL;,try,file=(,CInternetFile,*),session.OpenURL(URL,);,catch(CInternetException,*,pEx,),file=NULL;,pEx,-Delete();,if(file),m_out+=,已建立链接。,rn;,CString,line;,for(int,i=0;i,ReadString(line);i,+),m_out+=line+rn;,file-Close();,delete file;,else,m_out+=,本地址没有发现,http,主机,rn;,m_out+=-rn;,UpdateData(FALSE,);,下面,我们分析一下这个函数是如何实现,HTTP,链接的。首先,根据我们在第,9,章所学的知识,需要建立一个,Internet,会话,这就要定义一个,CInternetSession,的对象。其构造函数的原形如下:,CInternetSession(LPCTSTR,pstrAgent,=NULL, DWORD,dwContext,=1,DWORD,dwAccessType,=INTERNET_OPEN_TYPE_PRECONFIG,LPCTSTR,pstrProxyName,=NULL, LPCTSTR,pstrProxyBypass,=NULL,DWORD,dwFlags,=0);,这个函数需要定义很多参数,但本程序都使用缺省值,即“,=”,号后的值。,CInternetSession,构造函数参数说明如下:,LPCTSTR,pstrAgent,:,应用程序名,如果为,NULL,,,将填入在,AppWizard,中给定的程序名。,DWORD,dwContext,:,本操作的设备关联符定义。,DWORD,dwAccessType,:,访问类型,可以为以下参数之一:,INTERNET_OPEN_,TYPE_PRECONFIG(default),,,INTERNET_OPEN_TYPE_DIRECT,或,INTERNET_OPEN_,TYPE_PROXY,。,LPCTSTR,pstrProxyName,:,如访问类型为,INTERNET_OPEN_TYPE_PROXY,,,则给该参数赋予协议名称。,LPCTSTR,pstrProxyBypass,:,如访问类型为,INTERNET_OPEN_TYPE_PROXY,,,则该参数为不通过协议服务器而直接链接的一系列地址。,DWORD,dwFlags,:,可为以下参数:,INTERNET_FLAG_DONT_CACHE,,,INTERNET_,FLAG_ASYNC,和,INTERNET_FLAG_OFFLINE,。,DWORD,dwAccessType,:,值缺省时将使用系统注册簿定义的值。显然,程序允许使用者定义访问类型将比由程序内部直接定义要好。因此,要正确使用本程序,必须先在,Windows,系统中定义好网络访问类型,步骤如下:,(1),双击桌面上“我的电脑”图标。,(2),双击“控制面板”。,(3),点击“,Internet”,。,(4),在随后弹出的对话框中选择“连接”,然后填写网络连接属性。如果是通过拨号上网的,选中“拨号设置”选择项,并填写相关属性;如果是局域网,(LAN),上网的,则要进入局域网,(LAN),设置代理服务器的地址和端口号。,注意,:如果所使用的计算机已经接入,Internet,,,则不需要进行如上设置。,本程序在构造,CInternetSession,对象时使用缺省值,因此,构造函数将不带任何参数,如下所示:,CInternetSession,session;,在构造对象,session,后,如下两行程序进行输出提示,表示程序已开始工作:,m_out+=,正在链接,+URL+rn;,UpdateData(FALSE,);,接下来使用,session,对象的成员函数,OpenURL,(),来打开一个,URL,资源。该函数返回一个文件的指针,文件类型为以下四种之一:,file:/,如果访问的是本地机器,函数返回一个,CStudioFile,类对象的指针,ftp:/,如果访问的是,FTP,地址,函数返回一个,CInternetFile,类对象的指针,gopher,:,/,如果访问的是,Gopher,地址,函数返回一个,CGopherFile,类对象的指针,http,:,/,如果访问的是,HTTP,地址,函数返回一个,CHttpFile,类对象的指针,本程序用于访问远程机器,因此,函数不会返回一个,file:/,类型的本地文件。而,CGopherFile,和,CHttpFile,均派生自,CInternetFile,,,所以将该函数返回值赋给,CInternetFile,类的指针是安全的。当,OpenURL,(),不能正常打开,URL,资源时,该函数将会抛出一个异常,(exception),,,从而导致程序运行时错误。由于本程序用于探查未知的网址,该网址可能不提供相应服务或根本不存在,因此,OpenURL,(),有时可能不会正常运行。为了避免程序异常终止,我们需使用,try-catch,结构来处理异常。本段程序代码如下:,CInternetFile,* file=NULL;,try,file=(,CInternetFile,*),session.OpenURL(URL,);,catch(CInternetException,*,pEx,),file=NULL;/,如果发生运行时错误,给,file,赋空值,程序将继续运行,pEx,-Delete();,通过以上代码,程序将使用用户指定的地址来试图打开,HTTP,网址,如果失败,返回的文件为空,程序将继续运行,尝试用其他协议打开网址。随后,无论网址是否成功打开,我们都应作相应输出以提示用户。如果成功,用一个,for,循环读出返回文件的头,20,句并输出;如果失败,也要给出相应的提示。程序代码如下:,if(file) /,判定链接是否成功,m_out+=,已建立链接。,rn;,CString,line;,for(int,i=0;i,ReadString(line);i,+),m_out+=line+rn;,file-Close();,delete file;,else,m_out+=,本地址没有发现,http,主机,rn;,m_out+=-rn;,UpdateData(FALSE,);,用于查询的函数编写完后,还要给按钮的单击事件增加代码,以便按钮按下时程序开始查询。给按钮,IDC_BUTTON_HTTP,增加,BN_CLICKED,消息的代码如下:,void,CScanDlg:OnScanHttp,(),const,CString,http = http:/;,UpdateData(TRUE,);,m_out = ;,UpdateData(FALSE,);,TryURL(http,+ m_host);,TryURL(http,+ www. + m_host);,这段程序代码中,,UpdateData(TRUE,),的调用将给,m_host,赋予用户定义的值。,UpdateData(FALSE,),语句将清空输出编辑框变量,m_out,的内容,接下来调用两次,TryURL,(),。,例如,当用户输入,时,程序将首先试一试,,,然后试一试,。,到此为止,就可以编译程序并执行了。在该例中,我们在执行时输入,后,再单击“,HTPP”,按钮。在连接到,Internet,后,程序输出,主页的头,20,行,如图,10-9,所示。,图,10-9,服务器功能扫描程序对话框,3,FTP,协议查询代码,下面我们来探讨如何实现,FTP,链接。首先给对话框类增加一个实现链接的函数,TryFTP,代码如下:,void,CScanDlg:TryFTP(CString,host),CInternetSession,session;,m_out += ,正在链接,FTP,地址, + host + rn;,UpdateData(FALSE,);,CFtpConnection,* connection = NULL;,try,connection =,session.GetFtpConnection(host,);,catch (,CInternetException,*,pEx,),connection = NULL;,pEx,-Delete();,if (connection),m_out += ,已建立链接。,rn;,CString,line;,connection-,GetCurrentDirectory(line,);,m_out += ,缺省目录为, + line + rn;,connection-Close();,delete connection;,else,m_out += ,本地址没有发现,ftp,主机 。,rn;,m_out += -rn;,UpdateData(FALSE,);,本函数和,TryURL,(),很相似,不过它不使用,OpenURL,(),来打开一个文件,而用,GetFtpConnection,(),与,FTP,服务器建立链接。如果链接成功,将使用,GetCurrentDirectory,(),来得到服务器的缺省目录。,大多数,FTP,地址前有前缀,ftp.,,,一些早期的地址没有此前缀。现在,给,IDC_BUTTON_FTP,链接单击消息的处理函数,并编写如下程序代码:,void,CScanDlg:OnButtonFtp,(),UpdateData(TRUE,);,m_out = ;,UpdateData(FALSE,);,TryFTP(m_host,);,TryFTP(ftp,. + m_host);,现在已完成了,FTP,链接的实现代码。重新编译程序并运行,键入,,,可以发现在,处提供,ftp,服务。从程序开始查询到输出结果将有一段较长的时间,因为程序要等结果全部探查到后再显示,但实际上现在的商业,Internet,程序都是实时显示的。如果我们希望结果实时显示,就要使用异步套接口,(Asynchronous Sockets),或多线程编程。,4,Gopher,协议查询代码,Gopher,是一种基于文本的协议,它和,WWW,相似,可以通过点击链接点实现网络的链接和浏览。但是,,Gopher,是通过逐级文字菜单来组织链接和内容的,它不像,WWW,那样有丰富的多媒体页面。要实现,Gopher,查询,我们应给,CScanDlg,类增加另一个成员函数,void,TryGopher(CString,host),。,如果查询成功,该函数将返回查询地址的第一个,Gopher,位置,(locator),。,位置是,Gopher,协议的概念,任何,Gopher,客户程序必须先得到一个,Gopher,位置,然后才能进行相应的,Gopher,操作。,TryGopher,(),函数如下:,void,CScanDlg:TryGopher(CString,host),CInternetSession,session;,m_out += ,正在链接,gopher,地址, + host + rn;,UpdateData(FALSE,);,CGopherConnection,* connection = NULL;,try,connection =,session.GetGopherConnection(host,);,catch (,CInternetException,*,pEx,),connection = NULL;,pEx,-Delete();,if (connection),m_out += ,已建立链接。,rn;,CString,li
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 小学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!