�������� Linux Tags
23. ����Internet
���ڣ�����ֻ��Ҫ����һ֧�绰�Ϳ�����������Internet�����ҿ��Ժ��е����ʼ�λַ���˽���ȫ��ͨ�š��ر�����World Wide Web�ϣ������֡�ͼ�κͶ�ý�壨�������������ֺ���Ѷ����ʹ���Ѿ���չ��������Ѷ�ķ�Χ�͹��ܡ�
���Ҫ�ṩ����Windows��������Internet��س�ʽ�������ij��׽��ܣ����ܻ���Ҫ�ټ��ϼ�����Ź������ԣ�����ʵ������Ҫ�����������С�͵�Microsoft WindowsӦ�ó�ʽ�ܹ���Ч�ش�Internet��ȡ����Ѷ��������������������ֱ���Windows Sockets (Winsock) API��Windows Internet��WinInet��API֧Ԯ�ĵ�������Ð����FTP��File Transfer Protocol���IJ��֡�
Windows Sockets
��
Socket����University of California��Berkeley��У�����ĸ�������UNIX��ҵϵͳ��������·ͨѶ֧Ԯ�����↑����API���ڳ�Ϊ��Berkeley socket interface����
Sockets��TCP/IP
��
Socketͨ��������ר��춣�������Internetͨ�ŵĴ��������Ð��/������·Ð����TCP/IP��Transmission Control Protocol/Internet Protocol��ǣ����һ��������·Ð����IP��Internet Protocol������ΪTCP/IP����ɲ���֮һ�����������ϴ���ɡ����Ϸ����datagram�����������Ϸ��������춱�ʶ������Դ��Ŀ�ĵصı�ͷ��Ѷ�����������Ð����TCP��Transmission Control Protocol�����ṩ�˿ɿ��Ĵ���ͼ��IP���Ϸ����ȷ�Եķ�����
��TCP/IP�£�ͨѶ�˵���IPλַ�Ͳ��Ŷ��塣IPλַ����4��λԪ�飬���ȷ��Internet�ϵ��ŷ�����IPλַͨ�������ɵ�������ĸ�С�255�����֡��ĸ�ʽ��ʾ�����硸209.86.105.231��������ȷ�����ض��ķ�����ŷ����ṩ�ķ�������һЩ�����Ѿ���׼�������ṩ������֪�ķ���
��Socket��TCP/IP����ʱ��Socket����TCP/IP��ͨѶ�˵㡣��ˣ�Socketָ����IPλַ�Ͳ��š�
��·ʱ�����
��
��������ķ�����ʽ���ṩʱ��Ð����Time Protocol����Internet�ŷ��������ᡣ�˳�ʽ�����Ŀǰ׼ȷ�����ں�ʱ�䣬���ô���Ѷ�趨����PCʱ�ӡ�
�����������ұ�׼�ͼ���Ð�ᣨNational Institute of Standards and Technology������ǰ��Ϊ���ұ�׼�֣�National Bureau of Standards��������ά��׼ȷʱ�䣬��ʱ����������صĻ�������ϵ��׼ȷʱ���������ߵ�㲥���绰���롢���Բ��ŵ绰�����Լ�Internet�������Щ�������ļ���λ���վ
http://www.bldrdoc.gov/timefreq ���������ơ�bldrdoc��ָ����Boulder��Colorado��NIST Time��λ�ú�Frequency Division��������ֻ��NIST Network Time Service����Ȥ������ϸ���ļ�λ� http://www.bldrdoc.gov/timefreq/service/nts.htm ������ҳ�г���ʮ���ṩNISTʱ�������ŷ��������磬��һ������Ϊtime-a.timefreq.bldrdoc.gov����IPλַΪ132.163.135.130��
����������д��һ��ʹ�÷�Internet NIST���Բ��ӷ���ij�ʽ��������춡�PC Magazine������Ҳ������Ziff-Davis����վ http://www.zdnet.com/pcmag/pctech/content/16/20/ut1620.001.html ���ҵ����˳�ʽ�����ѧϰ���ʹ��Windows Telephony API���˺��а�������
��Internet����������ͬ��ʱ�����ÿһ������Request for Comment��RFC������ΪInternet��׼������Ð����Daytime Protocol����RFC-867���ṩ��һ��ASCII�ִ����ָ��׼ȷ�����ں�ʱ�䡣��ASCII�ִ���׼ȷ��ʽ������׼�������ǿ����������еĺ��塣ʱ��Ð����RFC-868���ṩ��һ��32λԪ�����֣�������ʾ��1900��1��1���������������ʱ����UTC����������ĸ˳������ʾ����ʱ�����꣨Coordinated Universal Time���������������ν�ĸ������α�׼ʱ�䣨Greenwich Mean Time������GMT��Ӣ����������ʱ�䡣������Ð����Ϊ��·ʱ��Ð����Network Time Protocol����RFC-1305������Ð���ܸ��ӡ�
������ǵ�Ŀ�ģ�����������Socket�Ͳ��ϸ���PCʱ�ӣ�ʱ��Ð��RFC-868�Ѿ������ˡ�RFC-868ֻ��һ����ҳ�ļ���ļ�����Ҫ��˵��TCP���׼ȷʱ��ij�ʽӦ�������²��裺
���������Ѿ�֪���˱�д��ȡʱ������SocketӦ�ó�ʽ��ÿ��ϸ�ڡ�
NETTIME��ʽ
��
Windows Sockets API��ͨ��Ҳ��ΪWinSock����Berkeley Sockets API���ݣ���ˣ���������UNIX Socket��ʽ�����˳�����õ�Windows��ʹ�á�Windows�¸���һ����֧Ԯ�ɶ�Berkeley Socket����Ĺ����ṩ���亯ʽ����ʽ����WSA����WinSock API����Ϊ���ס���صĸ����Ͳο�λ�/Platform SDK/Networking and Distributed Services/Windows Sockets Version 2��
NETTIME�����ʽ23-1��ʾ��չʾ��ʹ��WinSock API�ķ�����
��ʽ23-1 NETTIME NETTIME.C /*---------------------------------------------------------------------------- NETTIME.C -- Sets System Clock from Internet Services (c) Charles Petzold, 1998 -----------------------------------------------------------------------------*/ #include <windows.h> #include "resource.h" #define WM_SOCKET_NOTIFY (WM_USER + 1) #define ID_TIMER 1 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; BOOL CALLBACK MainDlg (HWND, UINT, WPARAM, LPARAM) ; BOOL CALLBACK ServerDlg (HWND, UINT, WPARAM, LPARAM) ; void ChangeSystemTime (HWND hwndEdit, ULONG ulTime) ; void FormatUpdatedTime (HWND hwndEdit, SYSTEMTIME * pstOld, SYSTEMTIME * pstNew) ; void EditPrintf (HWND hwndEdit, TCHAR * szFormat, ...) ; HINSTANCE hInst ; HWND hwndModeless ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("NetTime") ; HWND hwnd ; MSG msg ; RECT rect ; WNDCLASS wndclass ; hInst = hInstance ; wndclass.style = 0 ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = NULL ; wndclass.hbrBackground = NULL ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Set System Clock from Internet"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; // Create the modeless dialog box to go on top of the window hwndModeless = CreateDialog (hInstance, szAppName, hwnd, MainDlg) ; // Size the main parent window to the size of the dialog box. // Show both windows. GetWindowRect (hwndModeless, &rect) ; AdjustWindowRect (&rect, WS_CAPTION | WS_BORDER, FALSE) ; SetWindowPos ( hwnd, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE) ; ShowWindow (hwndModeless, SW_SHOW) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; // Normal message loop when a modeless dialog box is used. while (GetMessage (&msg, NULL, 0, 0)) { if (hwndModeless == 0 || !IsDialogMessage (hwndModeless, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_SETFOCUS: SetFocus (hwndModeless) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } BOOL CALLBACK MainDlg ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static char szIPAddr[32] = { "132.163.135.130" } ; static HWND hwndButton, hwndEdit ; static SOCKET sock ; static struct sockaddr_in sa ; static TCHAR szOKLabel[32] ; int iError, iSize ; unsigned long ulTime ; WORD wEvent, wError ; WSADATA WSAData ; switch (message) { case WM_INITDIALOG: hwndButton = GetDlgItem (hwnd, IDOK) ; hwndEdit = GetDlgItem (hwnd, IDC_TEXTOUT) ; return TRUE ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDC_SERVER: DialogBoxParam (hInst, TEXT ("Servers"), hwnd, ServerDlg, (LPARAM) szIPAddr) ; return TRUE ; case IDOK: // Call "WSAStartup" and display description text if (iError = WSAStartup (MAKEWORD(2,0), &WSAData)) { EditPrintf (hwndEdit, TEXT ("Startup error #%i.\r\n"), iError) ; return TRUE ; } EditPrintf (hwndEdit, TEXT ("Started up %hs\r\n"), WSAData.szDescription); // Call "socket" sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP) ; if (sock == INVALID_SOCKET) { EditPrintf (hwndEdit, TEXT ("Socket creation error #%i.\r\n"), WSAGetLastError ()) ; WSACleanup () ; return TRUE ; } EditPrintf (hwndEdit, TEXT ("Socket %i created.\r\n"), sock) ; // Call "WSAAsyncSelect" if (SOCKET_ERROR == WSAAsyncSelect (sock, hwnd, WM_SOCKET_NOTIFY, FD_CONNECT | FD_READ)) { EditPrintf ( hwndEdit, TEXT ("WSAAsyncSelect error #%i.\r\n"), WSAGetLastError ()) ; closesocket (sock) ; WSACleanup () ; return TRUE ; } // Call "connect" with IP address and time-server port sa.sin_family = AF_INET ; sa.sin_port = htons (IPPORT_TIMESERVER) ; sa.sin_addr.S_un.S_addr = inet_addr (szIPAddr) ; connect(sock, (SOCKADDR *) &sa, sizeof (sa)) ; // "connect" will return SOCKET_ERROR because even if it // succeeds, it will require blocking. The following only // reports unexpected errors. if (WSAEWOULDBLOCK != (iError = WSAGetLastError ())) { EditPrintf (hwndEdit, TEXT ("Connect error #%i.\r\n"), iError) ; closesocket (sock) ; WSACleanup () ; return TRUE ; } EditPrintf (hwndEdit, TEXT ("Connecting to %hs..."), szIPAddr) ; // The result of the "connect" call will be reported // through the WM_SOCKET_NOTIFY message. // Set timer and change the button to "Cancel" SetTimer (hwnd, ID_TIMER, 1000, NULL) ; GetWindowText (hwndButton, szOKLabel, sizeof (szOKLabel) /sizeof (TCHAR)) ; SetWindowText (hwndButton, TEXT ("Cancel")) ; SetWindowLong (hwndButton, GWL_ID, IDCANCEL) ; return TRUE ; case IDCANCEL: closesocket (sock) ; sock = 0 ; WSACleanup () ; SetWindowText (hwndButton, szOKLabel) ; SetWindowLong (hwndButton, GWL_ID, IDOK) ; KillTimer (hwnd, ID_TIMER) ; EditPrintf (hwndEdit, TEXT ("\r\nSocket closed.\r\n")) ; return TRUE ; case IDC_CLOSE: if (sock) SendMessage (hwnd, WM_COMMAND, IDCANCEL, 0) ; DestroyWindow (GetParent (hwnd)) ; return TRUE ; } return FALSE ; case WM_TIMER: EditPrintf (hwndEdit, TEXT (".")) ; return TRUE ; case WM_SOCKET_NOTIFY: wEvent = WSAGETSELECTEVENT (lParam) ; // ie, LOWORD wError = WSAGETSELECTERROR (lParam) ; // ie, HIWORD // Process two events specified in WSAAsyncSelect switch (wEvent) { // This event occurs as a result of the "connect" call case FD_CONNECT: EditPrintf (hwndEdit, TEXT ("\r\n")) ; if (wError) { EditPrintf ( hwndEdit, TEXT ("Connect error #%i."), wError) ; SendMessage (hwnd, WM_COMMAND, IDCANCEL, 0) ; return TRUE ; } EditPrintf (hwndEdit, TEXT ("Connected to %hs.\r\n"), szIPAddr) ; // Try to receive data. The call will generate an error // of WSAEWOULDBLOCK and an event of FD_READ recv (sock, (char *) &ulTime, 4, MSG_PEEK) ; EditPrintf (hwndEdit, TEXT ("Waiting to receive...")) ; return TRUE ; // This even occurs when the "recv" call can be made case FD_READ: KillTimer (hwnd, ID_TIMER) ; EditPrintf (hwndEdit, TEXT ("\r\n")) ; if (wError) { EditPrintf (hwndEdit, TEXT ("FD_READ error #%i."), wError) ; SendMessage (hwnd, WM_COMMAND, IDCANCEL, 0) ; return TRUE ; } // Get the time and swap the bytes iSize = recv (sock, (char *) &ulTime, 4, 0) ; ulTime = ntohl (ulTime) ; EditPrintf (hwndEdit, TEXT ("Received current time of %u seconds ") TEXT ("since Jan. 1 1900.\r\n"), ulTime) ; // Change the system time ChangeSystemTime (hwndEdit, ulTime) ; SendMessage (hwnd, WM_COMMAND, IDCANCEL, 0) ; return TRUE ; } return FALSE ; } return FALSE ; } BOOL CALLBACK ServerDlg ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static char * szServer ; static WORD wServer = IDC_SERVER1 ; char szLabel [64] ; switch (message) { case WM_INITDIALOG: szServer = (char *) lParam ; CheckRadioButton (hwnd, IDC_SERVER1, IDC_SERVER10, wServer) ; return TRUE ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDC_SERVER1: case IDC_SERVER2: case IDC_SERVER3: case IDC_SERVER4: case IDC_SERVER5: case IDC_SERVER6: case IDC_SERVER7: case IDC_SERVER8: case IDC_SERVER9: case IDC_SERVER10: wServer = LOWORD (wParam) ; return TRUE ; case IDOK: GetDlgItemTextA (hwnd, wServer, szLabel, sizeof (szLabel)) ; strtok (szLabel, "(") ; strcpy (szServer, strtok (NULL, ")")) ; EndDialog (hwnd, TRUE) ; return TRUE ; case IDCANCEL: EndDialog (hwnd, FALSE) ; return TRUE ; } break ; } return FALSE ; } void ChangeSystemTime (HWND hwndEdit, ULONG ulTime) { FILETIME ftNew ; LARGE_INTEGER li ; SYSTEMTIME stOld, stNew ; GetLocalTime (&stOld) ; stNew.wYear = 1900 ; stNew.wMonth = 1 ; stNew.wDay = 1 ; stNew.wHour = 0 ; stNew.wMinute = 0 ; stNew.wSecond = 0 ; stNew.wMilliseconds = 0 ; SystemTimeToFileTime (&stNew, &ftNew) ; li = * (LARGE_INTEGER *) &ftNew ; li.QuadPart += (LONGLONG) 10000000 * ulTime ; ftNew = * (FILETIME *) &li ; FileTimeToSystemTime (&ftNew, &stNew) ; if (SetSystemTime (&stNew)) { GetLocalTime (&stNew) ; FormatUpdatedTime (hwndEdit, &stOld, &stNew) ; } else EditPrintf (hwndEdit, TEXT ("Could NOT set new date and time.")) ; } void FormatUpdatedTime ( HWND hwndEdit, SYSTEMTIME * pstOld, SYSTEMTIME * pstNew) { TCHAR szDateOld [64], szTimeOld [64], szDateNew [64], szTimeNew [64] ; GetDateFormat (LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE | DATE_SHORTDATE, pstOld, NULL, szDateOld, sizeof (szDateOld)) ; GetTimeFormat ( LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE | TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, pstOld, NULL, szTimeOld, sizeof (szTimeOld)) ; GetDateFormat (LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE | DATE_SHORTDATE, pstNew, NULL, szDateNew, sizeof (szDateNew)) ; GetTimeFormat ( LOCALE_USER_DEFAULT, LOCALE_NOUSEROVERRIDE | TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, pstNew, NULL, szTimeNew, sizeof (szTimeNew)) ; EditPrintf (hwndEdit, TEXT ("System date and time successfully changed ") TEXT ("from\r\n\t%s, %s.%03i to\r\n\t%s, %s.%03i."), szDateOld, szTimeOld, pstOld->wMilliseconds, szDateNew, szTimeNew, pstNew->wMilliseconds) ; } void EditPrintf (HWND hwndEdit, TCHAR * szFormat, ...) { TCHAR szBuffer [1024] ; va_list pArgList ; va_start (pArgList, szFormat) ; wvsprintf (szBuffer, szFormat, pArgList) ; va_end (pArgList) ; SendMessage (hwndEdit, EM_SETSEL, (WPARAM) -1, (LPARAM) -1) ; SendMessage (hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) szBuffer) ; SendMessage (hwn dEdit, EM_SCROLLCARET, 0, 0) ; }
NETTIME.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Dialog SERVERS DIALOG DISCARDABLE 20, 20, 274, 202 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "NIST Time Service Servers" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,73,181,50,14 PUSHBUTTON "Cancel",IDCANCEL,150,181,50,14 CONTROL "time-a.timefreq.bldrdoc.gov (132.163.135.130) NIST, Boulder, Colorado", IDC_SERVER1,"Button",BS_AUTORADIOBUTTON,9,7,256,16 CONTROL "time-b.timefreq.bldrdoc.gov (132.163.135.131) NIST, Boulder, Colorado", IDC_SERVER2,"Button",BS_AUTORADIOBUTTON,9,24,256,16 CONTROL "time-c.timefreq.bldrdoc.gov (132.163.135.132) Boulder, Colorado", IDC_SERVER3,"Button",BS_AUTORADIOBUTTON,9,41,256,16 CONTROL "utcnist.colorado.edu (128.138.140.44) University of Colorado, Boulder", IDC_SERVER4,"Button",BS_AUTORADIOBUTTON,9,58,256,16 CONTROL "time.nist.gov (192.43.244.18) NCAR, Boulder, Colorado", IDC_SERVER5,"Button",BS_AUTORADIOBUTTON,9,75,256,16 CONTROL "time-a.nist.gov (129.6.16.35) NIST, Gaithersburg, Maryland", IDC_SERVER6,"Button",BS_AUTORADIOBUTTON,9,92,256,16 CONTROL "time-b.nist.gov (129.6.16.36) NIST, Gaithersburg, Maryland", IDC_SERVER7,"Button",BS_AUTORADIOBUTTON,9,109,256,16 CONTROL "time-nw.nist.gov (131.107.1.10) Microsoft, Redmond, Washington", IDC_SERVER8,"Button",BS_AUTORADIOBUTTON,9,126,256,16 CONTROL "utcnist.reston.mci.net (204.70.131.13) MCI, Reston, Virginia", IDC_SERVER9,"Button",BS_AUTORADIOBUTTON,9,143,256,16 CONTROL "nist1.data.com (209.0.72.7) Datum, San Jose, California", IDC_SERVER10,"Button",BS_AUTORADIOBUTTON,9,160,256,16 END NETTIME DIALOG DISCARDABLE 0, 0, 270, 150 STYLE WS_CHILD FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "Set Correct Time",IDOK,95,129,80,14 PUSHBUTTON "Close",IDC_CLOSE,183,129,80,14 PUSHBUTTON "Select Server...",IDC_SERVER,7,129,80,14 EDITTEXT IDC_TEXTOUT,7,7,253,110,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | NOT WS_TABSTOP END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by NetTime.rc #define IDC_TEXTOUT 101 #define IDC_SERVER1 1001 #define IDC_SERVER2 1002 #define IDC_SERVER3 1003 #define IDC_SERVER4 1004 #define IDC_SERVER5 1005 #define IDC_SERVER6 1006 #define IDC_SERVER7 1007 #define IDC_SERVER8 1008 #define IDC_SERVER9 1009 #define IDC_SERVER10 1010 #define IDC_SERVER 1011 #define IDC_CLOSE 1012
�ڽṹ�ϣ�NETTIME��ʽ������һ������NETTIME.RC�е�NETTIME�������ķ�ϵͳģ̬�Ի����顣��ʽ���¶������Ӵ��ijߴ磬�Ա��ϵͳģ̬�Ի�������Ը��dz�ʽ�������Ӵ���ʾ���ò¡£¶Ô»ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ò»ï¿½ï¿½Î¨ï¿½ï¿½ï¿½à¼ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ê½ï¿½ï¿½ï¿½Ð´ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ñ¶ï¿½ï¿½ï¿½ï¿½Ò»ï¿½ï¿½ï¿½ï¿½Select Server����ť��һ����Set Correct Time����ť��һ����Close����ť����Close����ť�����ֹ��ʽ��
MainDlg�е�szIPAddr������춴����ŷ���λַ���ڶ����ִ���132.163.135.130������Select Server����ť��������NETTIME.RC�е�SERVERSģ�彨���ĶԻ����顣szIPAddr������Ϊ����һ���������ݸ�DialogBoxParam����Server���Ի������г���10���ŷ��������Ǵ�NIST��վ�����ָ������ģ�����Щ�ŷ����ṩ�����Ǹ���Ȥ�ķ��񡣵�ʹ���ߵ���һ���ŷ���ʱ��ServerDlg��������ť���֣��Ի����Ӧ��IPλַ����λַ������szIPAddr�����С�
��ʹ���߰��¡�Set Correct Time����ťʱ����ť������һ��WM_COMMANDѶϢ������wParam�ĵ�������IDOK��MainDlg�е�IDOK�����Ǵ󲿷�Socket��ʼ��Ϊ�����ĵط���
ʹ��Windows Sockets APIʱ���κ�Windows��ʽ������еĵ�һ����ʽ�ǣ�
iError = WSAStartup (wVersion, &WSAData) ;
NETTIME����һ�������趨Ϊ0x0200����ʾ2.0�汾��������ʱ��WSAData�ṹ������Windows Socketsʵ���������Ѷ������NETTIME����ʾszDescription�ִ�������Ҫ�ṩ��һЩ�汾��Ѷ��
Ȼ�ᣬNETTIME���º���socket��ʽ��
sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP) ;
��һ��������һ��λַ���࣬��ʾ�˴���ij��Internetλַ���ڶ���������ʾ����������������ʽ���أ������������Ϸ������ʽ���أ�������Ҫ������ֻ��4��λԪ�鳤�������Ϸ������춽ϴ�����Ͽ飩������һ��������һ��Ð��������ָ��ʹ�õ�InternetÐ����TCP������RFC-868�����������Ð��֮һ��socket��ʽ�Ĵ���ֵ������SOCKET��̬�ı����У��Ա������Socket��ʽ�ĺ��С�
NETTIME������е�WSAAsynchSelect����һ��Windows���е�Socket��ʽ���˺�ʽ��춱�����Internet��Ӧ���������Ӧ�ó�ʽ��ס����WinSock�ļ��У���Щ��ʽ�롸�è°ï¿½Ô£ï¿½blocking�����йء�Ҳ����˵�����Dz��ܱ�֤�����ѿ�����Ȩ���ظ���ʽ��WSAAsyncSelect��ʽǿ���è°ï¿½ÔµÄºï¿½Ê½×ªÎªï¿½ï¿½ï¿½è°ï¿½ÔµÄ£ï¿½ï¿½ï¿½ï¿½Úºï¿½Ê½Ö´ï¿½ï¿½ï¿½ï¿½Ö®Ç°ï¿½Ñ¿ï¿½ï¿½ï¿½ï¿½î´«ï¿½Ø¸ï¿½ï¿½ï¿½Ê½ï¿½ï¿½ï¿½ï¿½Ê½ï¿½Ä½ï¿½ï¿½ï¿½ï¿½Ñ¶Ï¢ï¿½ï¿½ï¿½ï¿½Ê½ï¿½ï¿½ï¿½ï¿½ï¿½Ó¦ï¿½Ã³ï¿½Ê½ï¿½ï¿½WSAAsyncSelect��ʽ��Ӧ�ó�ʽָ��ѶϢ�ͽ���ѶϢ���Ӵ�����ֵ��ͨ������ʽ���﷨���£�
WSAAsyncSelect (sock, hwnd, message, iConditions) ;
Ϊ������NETTIMEʹ�ó�ʽ�����һ��ѶϢ����ѶϢ��ΪWM_SOCKET_NOTIFY����Ҳ��WSAAsyncSelect������һ��������ָ��ѶϢ���͵��������ر�������ͽ�������ʱ��FD_CONNECT | FD_READ����
NETTIME���е���һ��WinSock��ʽ��connect���˺�ʽ��Ҫһ��ָ��Socketλַ�ṹ��ָ�꣬��춲�ͬ��Ð����˵����Socketλַ�ṹ�Dz�ͬ�ġ�NETTIMEʹ��ΪTCP/IP��ƵĽṹ�汾��
struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; } ;
����in_addr�����ָ��Internetλַ����������4��λԪ�飬����2���������Ŷ�����������1���������ų���������ʾ��
NETTIME��sin_family��λ�趨ΪAF_INET����춱�ʾλַ���ࡣ��sin_port�趨Ϊ���ţ�������ʱ��Ð���IJ��ţ�RFC-868��ʾΪ37������Ҫ�������ʱ������������λ��Ϊ37�������������ͨ��Internetʱ���ṹ�����������λ�����ǡ�big endian���ģ�����ߵ�λԪ���ŵ�һ����Intel΢��������little endian�����˵��ǣ�htons����host-to-network short������ʽʹλԪ�é·×ªï¿½ï¿½ï¿½ï¿½ï¿½NETTIME��sockaddr_in�ṹ��sin_port��λ�趨Ϊ��
htons (IPPORT_TIMESERVER)
WINSOCK2.H�н���������Ϊ37��NETTIME��inet_addr��ʽ��������szIPAddr�ִ��е��ŷ���λַת��Ϊ�������ų�����������������趨�ṹ��sin_addr��λ��
���Ӧ�ó�ʽ��Windows 98�º���connect������ĿǰWindowsû�����ᵽInternet����ô����ʾ���������ߡ��Ի����顣�������ν�ġ��Զ����š�����Windows NT 4.0��û��ʵ�����Զ����š�����������NT������ִ�У���ô��ִ��NETTIME֮ǰ���ͱ�����������Internet��
connect��ʽͨ���Ѿ����è°ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ê½ï¿½ï¿½Ö´ï¿½Ð£ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Îªï¿½ï¿½ï¿½ï¿½É¹ï¿½ï¿½ï¿½Ç°ï¿½ï¿½Òªï¿½ï¿½Ð©Ê±ï¿½ä¡£È»ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½NETTIME������WSAAsyncSelect������connect����ȴ����ᣬ��ʵ�ϣ�������������SOCKET_ERROR��ֵ���Ⲣ���dz����˴�����ֻ�DZ�ʾ���ڻ�û�����߳ɹ����ѡ�NETTIMEҲ�������������ֵ��ֻ�Ǻ���WSAGetLastError���ѡ����WSAGetLastError����WSAEWOULDBLOCK������ʽ��ִ��ͨ��Ҫ���裬�����ﲢû�����裩���Ǿ�һ�ж�����������NETTIME����Set Correct Time����ť�ijɡ�Cancel�������趨��һ��1��ļ�ʱ����WM_TIMER�Ĵ�����ʽֻ���ڳ�ʽ�Ӵ�����ʾ��㣬�Ը���ʹ���߳�ʽ����ִ�У�ϵͳû�е�����
�����������ʱ��MainDlg��WM_SOCKET_NOTIFYѶϢ��NETTIME��WSAAsyncSelect��ʽ��ָ���ij�ʽ�Զ�ѶϢ��֪ͨ��lParam�ĵ�������FD_CONNECT���������ʾ������ʱ�Ĵ�������dz�ʽ�������ᵽָ�����ŷ�����NETTIME���г�������9���ŷ���������ѡ���������������������ŷ�����
���һ��˳������ôNETTIME������recv����receive�����ա�����ʽ����ȡ���ϣ�
recv (sock, (char *) &ulTime, 4, MSG_PEEK) ;
���������4��λԪ��������ulTime����������һ��������ʾֻ�Ƕ������ϣ��������������������ɾ������connect��ʽһ����recv����һ��������룬�Ա�ʾ��ʽͨ�����裬����ʱû�����衣��������˵����Ȼ�ⲻ����ܣ�����ʽ�����ܴ������ϵ�һ���֣�Ȼ��͸���ٴκ����Ի�������32��λԪ��ֵ���Ǿ��Ǻ���recv��ʽʱ����MSG_PEEKѡ���Ô��
��connect��ʽ���ƣ�recv��ʽҲ����WM_SOCKET_NOTIFYѶϢ����ʱ����FD_READ���¼����롣NETTIMEͨ���ٴκ���recv���Դ˻�Ӧ����ʱ����IJ�����0����춴�������ɾ�����ϡ��ҽ���Ҫ����һ�³�ʽ�������յ���ulTime�ķ�����ע�⣬NETTIMEͨ�����Լ�����WM_COMMANDѶϢ��������������ѶϢ��wParam���IDCANCEL���Ի��������ͨ������closesocket��WSACleanup����Ӧ��
�ٴκ���NETTIME���յ�32λԪ��ulTimeֵ�Ǵ�1990��1��1�տ�ʼ��0:00 UTC�����������˳���λԪ���ǵ�һ��λԪ�飬��˸�ֵ����ͨ��ntohl����network-to-host long������ʽ����������λԪ��˳���Ա�Intel΢�������ܹ�������Ȼ�ᣬNETTIME����ChangeSystemTime��ʽ��
ChangeSystemTime����ȡ��Ŀǰ�ı���ʱ�ä£ï¿½ï¿½ï¿½ï¿½Ê¹ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ê±ï¿½ï¿½ï¿½ï¿½ï¿½Õ¹ï¿½ï¿½Ô¼Ê±ï¿½ï¿½ï¿½Ä¿Ç°ÏµÍ³Ê±ï¿½ä¡£ï¿½ï¿½SYSTEMTIME�ṹ�趨Ϊ1900��1��1����ҹ��0ʱ�����������SYSTEMTIME�ṹ���ݸ�SystemTimeToFileTime�����˽ṹת��ΪFILETIME�ṹ��FILETIMEʵ����ֻ��������32λԪ��DWORDһ�����64λԪ��������������ʾ��1601��1��1��������Ϊ100���루nanosecond���ļ������
ChangeSystemTime��ʽ��FILETIME�ṹת��ΪLARGE_INTEGER������һ��union������64λԪ��ֵ���Ա���������32λԪ��ֵʹ�ã����ߵ���һ��__int64������̬��64λԪ����ʹ�ã�__int64������̬��Microsoft��������ANSI C��׼�����䣩����ˣ���ֵ��1601��1��1�յ�1900��1��1��֮����Ϊ100����ļ���������������1900��1��1��������Ϊ100����ļ������ulTime��10,000,000����
Ȼ��ͨ������FileTimeToSystemTime���������FILETIMEֵת����SYSTEMTIME�ṹ����Ϊʱ��Ð������Ŀǰ��UTCʱ�䣬����NETTIMEͨ������SetSystemTime���趨ʱ�䣬SetSystemTimeҲ����UTC�������ʾ��Ŀ�ģ���ʽ����GetLocalTime����ø���ʱ�䡣����ı���ʱ����µı���ʱ��һ�𴫵ݸ�FormatUpdatedTime�������ʽ��GetTimeFormat��ʽ��GetDateFormat��ʽ��ʱ��ת��ΪASCII�ִ���
�����ʽ��Windows NT��ִ�У�����ʹ����û��ȡ���趨ʱ�������Ȩ����ôSetSystemTime��ʽ����ʧ�ܡ����SetSystemTimeʧ�ܣ���NETTIME������һ����ʱ��δ�趨�ɹ���ѶϢ��ָ���������ڡ�
WININET��FTP
��
WinInet����Windows Internet����API��һ���߽׺�ʽ����������ʽд����ʹ������������InternetÐ����������Ð���ǣ����World Wide Webȫ����Ѷ���ij����ִ���Ð����HTTP��Hypertext Transfer Protocol������������Ð����FTP��File Transfer Protocol������һ����ΪGopher�ĵ�������Ð����WinInet��ʽ���﷨�볣�õ�Windows������ʽ���﷨���ƣ���ʹ��ʹ����ЩÐ������ʹ�ñ��شŵ����ϵĵ���һ�����ס�WinInet API���ļ�λ�/Platform SDK/Internet, Intranet, Extranet Services/Internet Tools and Technologies/WinInet API��
����ķ�����ʽ��չʾ���ʹ��WinInet API��FTP���֡���������վ�Ĺ�˾Ҳ���С�����FTP���ŷ���������ʹ���߿����ڲ�����ʹ�������ƺ��������������ص��������磬�������Internet Explorer��λַ������
ftp://ftp.microsoft.com ����ô���Ϳ������FTP�ŷ����ϵ�Ŀ¼�����ص������������ftp://ftp.cpetzold.com/cpetzold.com/ProgWin/UpdDemo����ô�������ҵ�����FTP�ŷ����Ϸ��������Ҫ�ᵽ�ķ�����ʽһ��ʹ�õĵ����б�����Ȼ�ֽ�FTP����Դ������Webʹ������˵��������ô����ʹ�ã�������Ȼ�൱���á����磬Ӧ�ó�ʽ������FTP������FTP�ŷ�����ȡ�����ϣ���Щȡ�����ϵ��������򼸺���ȫ��̨���´�����������Ҫʹ���߲��ġ���������ǽ����۵�UPDDEMO����update demonstration�����·���������ʽ�Ĺ��롣
FTP API�ſ�
��
ʹ��WinInet�ij�ʽ���������к���WinInet��ʽ��Ôʼ�����а�����ͷ����WININET.H����ʽ����������WININET.LIB����Microsoft Visual C++�У��������ڡ�Project Settings���Ի�����ġ�Link��ҳ���ǩ��ָ����ִ��ʱ����ʽ����WININET.DLL��̬�����ʽ�����ᡣ
������������У��Ҳ�����ϸ���ۺ�ʽ���﷨����ΪijЩ��ʽ�кܶ�ѡ�����������൱���ӡ�Ҫ����WinInet�������Խ�UPDDEMOÔʼ�뵱��ʳ������������ʱ����Ҫ�����˽��йصĸ��������Լ�FTP��ʽ�ķ�Χ��
Ҫʹ��Windows Internet API������Ҫ����InternetOpen��Ȼ�ᣬʹ��WinInet֧Ԯ���κ�һ��Ð����InternetOpen����һ��Internet��ҵ���ţ������浽HINTERNET��̬�ı����С�����WinInet API���ᣬӦ��ͨ������InternetCloseHandle���رմ��š�
Ҫʹ��FTP������������Ҫ����InternetConnect���˺�ʽ��Ҫʹ����InternetOpen����Internet��ҵ���ţ����Ҵ���FTP��ҵ�Ĵ��š����ɽ��˴�����Ϊ���ƿ�ͷΪFtp�����к�ʽ�ĵ�һ��������InternetConnect��ʽ�IJ���ָ��Ҫʹ�õ�FTP�����ṩ���ŷ������ƣ����磬ftp.cpetzold.com���˺�ʽ����Ҫʹ�������ƺ����롣�����ȡ����FTP�ŷ�������Щ���������趨ΪNULL�����Ӧ�ó�ʽ����InternetConnectʱPC��û�����ᵽInternet��Windows 98����ʾ���������ߡ��Ի����顣��ʹ��FTP��Ӧ�ó�ʽ����ʱ������InternetCloseHandle���رմ��š�
��ʱ���Կ�ʼ������Ftp���׵ĺ�ʽ������������Щ��ʽ���׼��Windows����I/O��ʽ�����ơ�Ϊ�˱���������Ð���ظ���һЩ��InternetΪ���׵ĺ�ʽҲ���Դ���FTP��
�����ĸ���ʽ��춴���Ŀ¼��
fSuccess = FtpCreateDirectory (hFtpSession, szDirectory) ; fSuccess = FtpRemoveDirectory (hFtpSession, szDirectory) ; fSuccess = FtpSetCurrentDirectory (hFtpSession, szDirectory) ; fSuccess = FtpGetCurrentDirectory (hFtpSession, szDirectory, &dwCharacterCount) ;
ע�⣬��Щ��ʽ������������Ϥ��Windows�ṩ��춴������ص���ϵͳ��CreateDirectory��RemoveDirectory��SetCurrentDirectory��GetCurrentDirectory��ʽ��
��Ȼ����ȡ����FTP��Ӧ�ó�ʽ���ܽ�����ɾ��Ŀ¼�����ң���ʽҲ���ܼٶ�FTPĿ¼���к�Windows����ϵͳ��ͬ��Ŀ¼�ṹ��̬���ر��������·�����趨Ŀ¼�ij�ʽ�����ܼٶ�����µ�Ŀ¼ȫ����һ�С������ʽ��Ҫ֪����������Ŀ¼���������ƣ���ô������SetCurrentDirectory֮������ٺ���GetCurrentDirectory��GetCurrentDirectory���ִ��������ٰ���MAX_PATH��Ԫ����������һ������Ӧָ�������ֵ�ı�����
����������ʽ����ɾ��������������������������������FTP�ŷ����ϣ���
fSuccess = FtpDeleteFile (hFtpSession, szFileName) ; fSuccess = FtpRenameFile (hFtpSession, szOldName, szNewName) ;
�����Ⱥ���FtpFindFirstFile�����Բ��ҵ��������뺬��������Ԫ�ĵ�����ʽ����Ķ�����������˺�ʽ����FindFirstFile��ʽ��������ʹ������ͬ��WIN32_FIND_DATA�ṹ���õ���Ϊ�оٳ����ĵ���������һ�����š������Խ��˴��Ŵ��ݸ�InternetFindNextFile��ʽ�Ի�ö���ĵ���������Ѷ������ͨ������InternetCloseHandle���رմ��š�
Ҫ�򿪵��������Ժ���FtpFileOpen�������ʽ����һ���������ţ��˴��ſ������InternetReadFile��InternetReadFileEx��InternetWrite��InternetSetFilePointer���С��������ͨ��������õ�InternetCloseHandle��ʽ���رմ��š�
���ᣬ���������߼���ʽ�ر����ã�FtpGetFile���н�������FTP�ŷ������Ƶ����ؼ����壬���ϲ���FtpFileOpen��FileCreate��InternetReadFile��WriteFile��InternetCloseHandle��CloseHandle���С�FtpGetFile����һ��������һ����꣬��������Ѿ�����ͬ����������ô����꽫���º�ʽ����ʧ�ܡ�FtpPutFile��˺�ʽ���ƣ���춽������ӱ��ؼ����帴�Ƶ�FTP�ŷ�����
����չʾ��ʽ
��
UPDDEMO�����ʽ23-2��ʾ��չʾ����WinInet FTP��ʽ�ڵڶ���ִ����ִ���ڼ������FTP�ŷ��������ص����ķ�����
��ʽ23-2 UPDDEMO UPDDEMO.C /*--------------------------------------------------------------------------- UPDDEMO.C -- Demonstrates Anonymous FTP Access (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> #include <wininet.h> #include <process.h> #include "resource.h" // User-defined messages used in WndProc #define WM_USER_CHECKFILES (WM_USER + 1) #define WM_USER_GETFILES (WM_USER + 2) // Information for FTP download #define FTPSERVER TEXT ("ftp.cpetzold.com") #define DIRECTORY TEXT ("cpetzold.com/ProgWin/UpdDemo") #define TEMPLATE TEXT ("UD??????.TXT") // Structures used for storing filenames and contents typedef struct { TCHAR * szFilename ; char * szContents ; } FILEINFO ; typedef struct { int iNum ; FILEINFO info[1] ; } FILELIST ; // Structure used for second thread typedef struct { BOOL bContinue ; HWND hwnd ; } PARAMS ; // Declarations of all functions in program LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; BOOL CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM) ; VOID FtpThread (PVOID) ; VOID ButtonSwitch (HWND, HWND, TCHAR *) ; FILELIST * GetFileList (VOID) ; int Compare (const FILEINFO *, const FILEINFO *) ; // A couple globals HINSTANCE hInst ; TCHAR szAppName[] = TEXT ("UpdDemo") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; hInst = hInstance ; wndclass.style = 0 ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = NULL ; wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Update Demo with Anonymous FTP"), WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; // After window is displayed, check if the latest file exists SendMessage (hwnd, WM_USER_CHECKFILES, 0, 0) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static FILELIST * plist ; static int cxClient, cyClient, cxChar, cyChar ; HDC hdc ; int i ; PAINTSTRUCT ps ; SCROLLINFO si ; SYSTEMTIME st ; TCHAR szFilename [MAX_PATH] ; switch (message) { case WM_CREATE: cxChar = LOWORD (GetDialogBaseUnits ()) ; cyChar = HIWORD (GetDialogBaseUnits ()) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; si.cbSize = sizeof (SCROLLINFO) ; si.fMask = SIF_RANGE | SIF_PAGE ; si.nMin = 0 ; si.nMax = plist ? plist->iNum - 1 : 0 ; si.nPage = cyClient / cyChar ; SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ; return 0 ; case WM_VSCROLL: si.cbSize = sizeof (SCROLLINFO) ; si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE ; GetScrollInfo (hwnd, SB_VERT, &si) ; switch (LOWORD (wParam)) { case SB_LINEDOWN: si.nPos += 1 ; break ; case SB_LINEUP: si.nPos -= 1 ; break ; case SB_PAGEDOWN: si.nPos += si.nPage ; break ; case SB_PAGEUP: si.nPos -= si.nPage ; break ; case SB_THUMBPOSITION: si.nPos = HIWORD (wParam) ; break ; default: return 0 ; } si.fMask = SIF_POS ; SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ; InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case WM_USER_CHECKFILES: // Get the system date & form filename from year and month GetSystemTime (&st) ; wsprintf (szFilename, TEXT ("UD%04i%02i.TXT"), st.wYear, st.wMonth) ; // Check if the file exists; if so, read all the files if (GetFileAttributes (szFilename) != (DWORD) -1) { SendMessage (hwnd, WM_USER_GETFILES, 0, 0) ; return 0 ; } // Otherwise, get files from Internet. // But first check so we don't try to copy files to a CD-ROM! if (GetDriveType (NULL) == DRIVE_CDROM) { MessageBox (hwnd, TEXT ("Cannot run this program from CD-ROM!"), szAppName, MB_OK | MB_ICONEXCLAMATION) ; return 0 ; } // Ask user if an Internet connection is desired if (IDYES == MessageBox (hwnd, TEXT ("Update information from Internet?"), szAppName, MB_YESNO | MB_ICONQUESTION)) // Invoke dialog box DialogBox (hInst, szAppName, hwnd, DlgProc) ; // Update display SendMessage (hwnd, WM_USER_GETFILES, 0, 0) ; return 0 ; case WM_USER_GETFILES: SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; // Read in all the disk files plist = GetFileList () ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; // Simulate a WM_SIZE message to alter scroll bar & repaint SendMessage (hwnd, WM_SIZE, 0, MAKELONG (cxClient, cyClient)) ; InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SetTextAlign (hdc, TA_UPDATECP) ; si.cbSize = sizeof (SCROLLINFO) ; si.fMask = SIF_POS ; GetScrollInfo (hwnd, SB_VERT, &si) ; if (plist) { for (i = 0 ; i < plist->iNum ; i++) { MoveToEx (hdc, cxChar, (i - si.nPos) * cyChar, NULL) ; TextOut (hdc, 0, 0, plist->info[i].szFilename, lstrlen (plist->info[i].szFilename)) ; TextOut (hdc, 0, 0, TEXT (": "), 2) ; TextOutA (hdc, 0, 0, plist->info[i].szContents, strlen (plist->info[i].szContents)) ; } } EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } BOOL CALLBACK DlgProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static PARAMS params ; switch (message) { case WM_INITDIALOG: params.bContinue = TRUE ; params.hwnd = hwnd ; _beginthread (FtpThread, 0, ¶ms) ; return TRUE ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDCANCEL: // button for user to abort download params.bContinue = FALSE ; return TRUE ; case IDOK: // button to make dialog box go away EndDialog (hwnd, 0) ; return TRUE ; } } return FALSE ; } /*--------------------------------------------------------------------------- FtpThread: Reads files from FTP server and copies them to local disk -----------------------------------------------------------------------------*/ void FtpThread (PVOID parg) { BOOL bSuccess ; HINTERNET hIntSession, hFtpSession, hFind ; HWND hwndStatus, hwndButton ; PARAMS * pparams ; TCHAR szBuffer [64] ; WIN32_FIND_DATA finddata ; pparams = parg ; hwndStatus = GetDlgItem (pparams->hwnd, IDC_STATUS) ; hwndButton = GetDlgItem (pparams->hwnd, IDCANCEL) ; // Open an internet session hIntSession = InternetOpen (szAppName, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC) ; if (hIntSession == NULL) { wsprintf (szBuffer, TEXT ("InternetOpen error %i"), GetLastError ()) ; ButtonSwitch (hwndStatus, hwndButton, szBuffer) ; _endthread () ; } SetWindowText (hwndStatus, TEXT ("Internet session opened...")) ; // Check if user has pressed Cancel if (!pparams->bContinue) { InternetCloseHandle (hIntSession) ; ButtonSwitch (hwndStatus, hwndButton, NULL) ; _endthread () ; } // Open an FTP session. hFtpSession = InternetConnect (hIntSession, FTPSERVER, INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, 0, 0) ; if (hFtpSession == NULL) { InternetCloseHandle (hIntSession) ; wsprintf (szBuffer, TEXT ("InternetConnect error %i"), GetLastError ()) ; ButtonSwitch (hwndStatus, hwndButton, szBuffer) ; _endthread () ; } SetWindowText (hwndStatus, TEXT ("FTP Session opened...")) ; // Check if user has pressed Cancel if (!pparams->bContinue) { InternetCloseHandle (hFtpSession) ; InternetCloseHandle (hIntSession) ; ButtonSwitch (hwndStatus, hwndButton, NULL) ; _endthread () ; } // Set the directory bSuccess = FtpSetCurrentDirectory (hFtpSession, DIRECTORY) ; if (!bSuccess) { InternetCloseHandle (hFtpSession) ; InternetCloseHandle (hIntSession) ; wsprintf ( szBuffer, TEXT ("Cannot set directory to %s"), DIRECTORY) ; ButtonSwitch (hwndStatus, hwndButton, szBuffer) ; _endthread () ; } SetWindowText (hwndStatus, TEXT ("Directory found...")) ; // Check if user has pressed Cancel if (!pparams->bContinue) { InternetCloseHandle (hFtpSession) ; InternetCloseHandle (hIntSession) ; ButtonSwitch (hwndStatus, hwndButton, NULL) ; _endthread () ; } // Get the first file fitting the template hFind = FtpFindFirstFile (hFtpSession, TEMPLATE, &finddata, 0, 0) ; if (hFind == NULL) { InternetCloseHandle (hFtpSession) ; InternetCloseHandle (hIntSession) ; ButtonSwitch (hwndStatus, hwndButton, TEXT ("Cannot find files")) ; _endthread () ; } do { // Check if user has pressed Cancel if (!pparams->bContinue) { InternetCloseHandle (hFind) ; InternetCloseHandle (hFtpSession) ; InternetCloseHandle (hIntSession) ; ButtonSwitch (hwndStatus, hwndButton, NULL) ; _endthread () ; } // Copy file from internet to local hard disk, but fail // if the file already exists locally wsprintf (szBuffer, TEXT ("Reading file %s..."), finddata.cFileName) ; SetWindowText (hwndStatus, szBuffer) ; FtpGetFile ( hFtpSession, finddata.cFileName, finddata.cFileName, TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 0) ; } while (InternetFindNextFile (hFind, &finddata)) ; InternetCloseHandle (hFind) ; InternetCloseHandle (hFtpSession) ; InternetCloseHandle (hIntSession) ; ButtonSwitch (hwndStatus, hwndButton, TEXT ("Internet Download Complete")); } /*---------------------------------------------------------------------------- ButtonSwitch: Displays final status message and changes Cancel to OK -------------------------------------------------------------------------*/ VOID ButtonSwitch (HWND hwndStatus, HWND hwndButton, TCHAR * szText) { if (szText) SetWindowText (hwndStatus, szText) ; else SetWindowText (hwndStatus, TEXT ("Internet Session Cancelled")) ; SetWindowText (hwndButton, TEXT ("OK")) ; SetWindowLong (hwndButton, GWL_ID, IDOK) ; } /*--------------------------------------------------------------------------- GetFileList: Reads files from disk and saves their names and contents -----------------------------------------------------------------------------*/ FILELIST * GetFileList (void) { DWORD dwRead ; FILELIST * plist ; HANDLE hFile, hFind ; int iSize, iNum ; WIN32_FIND_DATA finddata ; hFind = FindFirstFile (TEMPLATE, &finddata) ; if (hFind == INVALID_HANDLE_VALUE) return NULL ; plist = NULL ; iNum = 0 ; do { // Open the file and get the size hFile = CreateFile (finddata.cFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL) ; if (hFile == INVALID_HANDLE_VALUE) continue ; iSize = GetFileSize (hFile, NULL) ; if (iSize == (DWORD) -1) { CloseHandle (hFile) ; continue ; } // Realloc the FILELIST structure for a new entry plist = realloc (plist, sizeof (FILELIST) + iNum * sizeof (FILEINFO)); // Allocate space and save the filename plist->info[iNum].szFilename = malloc (lstrlen (finddata.cFileName) +sizeof (TCHAR)) ; lstrcpy (plist->info[iNum].szFilename, finddata.cFileName) ; // Allocate space and save the contents plist->info[iNum].szContents = malloc (iSize + 1) ; ReadFile (hFile, plist->info[iNum].szContents, iSize, &dwRead, NULL); plist->info[iNum].szContents[iSize] = 0 ; CloseHandle (hFile) ; iNum ++ ; } while (FindNextFile (hFind, &finddata)) ; FindClose (hFind) ; // Sort the files by filename qsort (plist->info, iNum, sizeof (FILEINFO), Compare) ; plist->iNum = iNum ; return plist ; } /*--------------------------------------------------------------------------- Compare function for qsort ----------------------------------------------------------------------------*/ int Compare (const FILEINFO * pinfo1, const FILEINFO * pinfo2) { return lstrcmp (pinfo2->szFilename, pinfo1->szFilename) ; }
UPDDEMO.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Dialog UPDDEMO DIALOG DISCARDABLE 20, 20, 186, 95 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Internet Download" FONT 8, "MS Sans Serif" BEGIN PUSHBUTTON Cancel",IDCANCEL,69,74,50,14 CTEXT "",IDC_STATUS,7,29,172,21 END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by UpdDemo.rc #define IDC_STATUS 40001
UPDDEMOʹ�õĵ���������UDyyyymm.TXT������yyyy��4λ���������ֵ���������Ȼ�����2000����mm��2λ���������ֵ�����������ٶ���ʽ��������ÿ���¶��и��µ����ĺô�����Щ���������������¿���������Ķ�Ч���ϵĿ��ǣ��ó�ʽ�������ص����ش���ý���ϡ�
��ˣ�WinMain�ں���ShowWindow��UpdateWindow����ʾUPDDEMO���Ӵ����ᣬ��WndProc���ͳ�ʽ�����WM_USER_CHECKFILESѶϢ��WndProcͨ�����Ŀǰ���ꡢ�²���������UDyyyymm.TXT�������ڵ��ڶ�Ŀ¼��������ѶϢ�����ֵ����Ĵ����������UPDDEMO�ᱻ��ȫ���£���Ȼ����ʵ������ˡ�һЩ��ʱ�ĵ�����©�������Ҫ���ø���������ʽ�ý��и��㷺�ļ�⣩������������£�UPDDEMO���Լ�����һ��WM_USER_GETFILESѶϢ����ͨ������GetFileList��ʽ������������UPDDEMO.C���Գ���һ����ʽ�������������ر����ã���������ȫ���������ǽ����е�UDyyyymm.TXT����������̬���õ�FILELIST��̬�ṹ�У��ýṹ���ڳ�ʽ��������ģ�Ȼ���ó�ʽ������ʾ������ʾ��Щ���������ݡ�
���UPDDEMOû�����µĵ�������ô������͸��Internet���и��¡���ʽ����ѯ��ʹ�����������Ƿ�OK��������ǣ���ʽ����ʾһ���򵥵ĶԻ����飬����ֻ��һ����Cancel����ť��һ��IDΪIDC_STATUS�ľ�̬������������ʱ���˾�̬��������ʹ�����ṩ״̬���棬��������ʹ����ȡ����춻����ĸ�����ҵ���˶Ի������������DlgProc��
DlgProc�̣ܶ���������һ�����������Ӵ����ŵ�PARAMS��̬�Ľṹ�Լ�һ������ΪbContinue��BOOL������Ȼ�����_ beginthread��ִ�еڶ���ִ������
FtpThread��ʽ͸��ʹ������ĺ��������ʵ�ʵĴ��䣺InternetOpen��InternetConnect��FtpSetCurrentDirectory��FtpFindFirstFile��InternetFindNextFile��FtpGetFile��InternetCloseHandle�����Σ�����ͬ�������ʽ�룬��ִ������ʽ����Թ������顢��ʹ�����˽���һ���IJ�������Լ�����ʹ��������ȡ��������ʾ����Щ���裬��ô������ü�����ࡣFtpThread��ʽ͸����hwndStatus���ź���SetWindowText����ʹ����֪����չ���������ָ���ǶԻ������м�ľ�̬��������
ִ��������������������ַ�ʽ֮һ����ֹ��
��һ�֣�FtpThread����������WinInet��ʽ���صĴ��������������������������Ŵ����ִ��ĸ�ʽ��Ȼ�Ὣ���ִ�����ͬ�Ի��������������ź͡�Cancel����ť�Ĵ���һ�𣩴��ݸ�ButtonSwitch��ButtonSwitch��һ��С��ʽ������ʾ�������ִ���������Cancel����ťת���ɡ�OK����ť����ֻ�ǰ�ť�ϵ������ִ���ת����������������ID��ת��������������ʹ���߰��¡�OK����ť�������Ի����顣
�ڶ��ַ�ʽ��FtpThread����û���κδ�����������������䴦����������������ʱ�ķ���һ����ֻ�����Ի���������ʾ���ִ�Ϊ��Internet Download Complete����
�����ַ�ʽ��ʹ���߿����ڳ�����ѡ��ȡ�����ء���ʱ��DlgProc��PARAMS�ṹ��bContinue��λ�趨ΪFALSE��FtpThreadƵ���ؼ���ֵ�����bContinue���FALSE����ô��ʽ������Ӧ�ý��е���ʰ����������NULL���ֲ�������ButtonSwitch���˲�����ʾ��ʾ���ִ���Internet Session Cancelled����ͬ����ʹ���߱��밴�¡�OK����ť���رնԻ����顣
��ȻUPDDEMOȡ�õ�ÿ������ֻ����ʾһ�У����ң���������ߣ������������ʽ��������������Ķ��ߣ�����ĸ��������Լ�������Ѷ����Ҳ��������վ�Ϸ��ָ���ϸ����Ѷ����ˣ�UPDDEMO��Ϊ������������Ѷ�ķ��������ҿ����ñ������������������һҳ֮�ᡣ