Каталог :: Коммуникации и связь

Курсовая: Программа просмотра свободного места на жестком диске сервера

                                
     ЧЕЛЯБИНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
                                      ОТЧЕТ                                      
                 о практической работе по дисциплине «Сети ЭВМ»                 
Факультет: математический                 Выполнили: Евсеева М.С.
                                                         Переславцев Н.А.
Специальность: прикладная                  Группа: МП-402
     математика
Кафедра:  системного                              Проверил: Соколов
Андрей Анатольевич
     программирования
                                 Челябинск 2004                                 
     

1. Задание.......................3

2. Используемые сетевые сообщения........3

3. Основные функции программы..........4

4. Диаграмма процессов.................5

5. Работа программы.................6

6. Текст программы..................7

1. Задание.

Разработать приложения клиент - сервер для отправки данных о наличии свободного места на жестком диске сервера с использованием UDP протокола. Клиент «активный», сервер «пассивный».

2. Используемые сетевые сообщения.

В программе использованы следующие 5 видов пакетов: 1) «установки соединения». Запрос соединения. (Connect) 2) «установки соединения». Ответ на запрос соединения. (Accept) 3) «ожидание-проверка соединения». Периодическая проверка наличия соединения. (Ping) 4) «запрос информации у сервера». Запрос данных о свободном пространстве на диске. (Info (i)) 5) «получения информации от сервера». Периодическая отправка данных о свободном месте на диске. (Info (r)) Пакеты 1) – 5) имеют следующий формат. union packd { char buff[63]; // буфер struct pack p; // данные }; где struct pack{ char action; // Тип пакета DWORD t; // t - Число свободных килобайт } ar;

3. Основные функции, используемые в программе.

ü void ServerStop; (остановка сервера) ü void initme; (создание сокета сервера, клиента, ожидание соединения на всех сетевых интерфейсах) ü bool clientconnect; (создание потока соединения клиента с сервером) ü void StartServer; (создание и запуск потока сервера ) ü DWORD WINAPI ThreadAction_put, DWORD WINAPI ThreadAction_cl, DWORD WINAPI ThreadAction_serv; (потоки клиента и сервера обработки данных) ü void drawme; (обновление полей таблицы с данными о свободном месте за последние секунды) ü CHAR * get_error_text(int code), void err(char * pl); (проверка типа ошибки и формирование соответствующего коду предупреждения о ней) ü GetDiskFreeSpace; (получение информации о количестве свободного места на диске)

4. Диаграмма процессов.

5. Работа программы.

6. Текст программы.

#include "stdafx.h" #include "resource.h" #include <winsock2.h> #include <math.h> #include <stdlib.h> #include <stdio.h> #define MAX_LOADSTRING 100 /* * Client interaction routine data */ struct pack{ char action; DWORD t; } ar; DWORD space, ss[5]; union packd { char buff[63]; struct pack p; }; int tr = 0, trd = 0; /* * socket address type converter routine */ void err(char * pl); void drawme(HWND hWnd); void ServerStop(HWND hWnd); HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text // Foward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); bool iamserv = false, started = false, iamclient = false, alive = false; SOCKET s,s_cl=0; SOCKADDR_IN dest_sin; struct sockaddr_in caddr; struct sockaddr_in saddr; struct sockaddr_in local_cl; HANDLE thread, thread_cl, thread_put; #define SERV_PORT 55555 #define CLNT_PORT 55556 struct timeval tv; HANDLE finished, finished_cl, finished_draw,finished_put; CHAR * get_error_text(int code) { switch (code) { case (WSANOTINITIALISED): return "Winsock was not initialized"; case (WSAENETDOWN): return "Network subsystem failed"; case (WSAEADDRINUSE): return "local addres already used"; case (WSAEINTR): return "call cancelled"; case (WSAEINPROGRESS): return "operation in progress"; case (WSAEALREADY): return "already connecting"; case (WSAEADDRNOTAVAIL): return "local address not available"; case (WSAEAFNOSUPPORT): return "address family not supported"; case (WSAECONNREFUSED): return "connection refused (port closed)"; case (WSAEFAULT): return "memory access violation"; case (WSAEINVAL): return "invalid socket operation"; case (WSAEISCONN): return "already connected"; case (WSAENETUNREACH): return "network unreachable"; case (WSAENOBUFS): return "no buffer space available"; case (WSAENOTSOCK): return "not a socket"; case (WSAETIMEDOUT): return "timeout"; case (WSAEWOULDBLOCK): return "socket nonblocking, but operation blocks"; case (WSAEACCES): return "broadcast address given"; } return "Unknown error"; } PTHREAD_DATA dt=NULL; DWORD WINAPI ThreadAction_serv(LPVOID param) { union packd p; memset(&p,0,sizeof(p)); struct sockaddr_in addr; addr.sin_addr.s_addr = INADDR_ANY; int size = sizeof(caddr),tmp = -1,e, suc; fd_set rfds; struct timeval tv; HWND hWnd = HWND(param); FD_ZERO(&rfds); FD_SET(s, &rfds); tv.tv_sec = 8192; tv.tv_usec = 0; char szDir[4]; szDir[0] = TEXT('C'); szDir[1] = TEXT(':'); szDir[2] = TEXT('\\'); szDir[3] = 0; DWORD lpSectorsPerCluster; DWORD lpBytesPerSector; DWORD lpNumberOfFreeClusters; DWORD lpTotalNumberOfClusters; int retval = select(1, &rfds, NULL, NULL, &tv); while (retval) { e = recvfrom(s,p.buff, sizeof(p.buff)+1,0,(sockaddr*)&caddr,&size); if (addr.sin_addr.s_addr == INADDR_ANY) {addr.sin_addr.s_addr = caddr.sin_addr.s_addr;}; if ((addr.sin_addr.s_addr != INADDR_ANY) && addr.sin_addr.s_addr != caddr.sin_addr.s_addr ) { MessageBox(NULL,"Wrong client","At server got: ",MB_OK); } else { alive = true; } caddr.sin_port = htons(CLNT_PORT); switch(p.p.action){ case('p'): e = sendto(s_cl, p.buff, sizeof(p)+1,0,(PSOCKADDR)&caddr, sizeof(caddr)); if (e == -1) err("serv ping send"); started = true; break; case('i'): suc = GetDiskFreeSpace(szDir,&lpSectorsPerCluster, &lpBytesPerSector, &lpNumberOfFreeClusters, &lpTotalNumberOfClusters); space = lpSectorsPerCluster * lpBytesPerSector / 1024 * lpNumberOfFreeClusters; p.p.t = space; p.p.action = 'r'; e = sendto(s_cl, p.buff, sizeof(p)+1,0,(PSOCKADDR)&caddr, sizeof(caddr)); if (e == -1) err("serv info send"); break; } tv.tv_sec = 8 * 60; retval = select(1, &rfds, NULL, NULL, &tv); } MessageBox(NULL,"end of serv die to timeout...","tip",MB_OK); closesocket(s); SetEvent(finished); return(1); } DWORD WINAPI ThreadAction_cl(LPVOID param) { memset(&ss,0,sizeof(ss)); union packd p; char i,k=5; memset(&p,0,sizeof(p)); struct sockaddr_in addr; int size = sizeof(addr),tmp,e; fd_set rfds; struct timeval tv; HWND hWnd = HWND(param); lstrcpy(p.buff,"ppppp"); // CHANGE IP ADDRESS OF SERVER saddr.sin_addr.s_addr = inet_addr("127.168.86.171"); p.p.action = 'p'; sendto(s, p.buff, sizeof(p)+1,0,(PSOCKADDR)&saddr, sizeof(saddr)); if (e == -1) err("client 1st ping send"); tv.tv_sec = 8; tv.tv_usec = 0; int retval; while (k) { FD_ZERO(&rfds); FD_SET(s_cl, &rfds); retval = select(1, &rfds, NULL, NULL, &tv); while (retval) { e = recvfrom(s_cl,p.buff,sizeof(p.buff)+1,0,(sockaddr*)&addr,&size); alive = true; saddr.sin_port = htons(SERV_PORT); switch(p.p.action) { case('p'): Sleep(1000); e = sendto(s, p.buff, sizeof(p)+1,0,(PSOCKADDR)&saddr, sizeof(saddr)); if (e == -1) err("client ping send"); started = true; break; case('r'): space = p.p.t; for (i=0;i<=4;i++) { ss[i] = ss[i+1]; }; ss[5]=space; drawme(hWnd); trd++; tr = 0; break; } memset(&p,0,sizeof(p)); k=5; } p.p.action = 'p'; alive = false; Sleep(8000); e = sendto(s, p.buff, sizeof(p)+1,0,(PSOCKADDR)&saddr, sizeof(saddr)); if (e == -1) err("client ping again send"); k--; } MessageBox(NULL,"end of client (ie timeout...)","tip",MB_OK); closesocket(s_cl); SetEvent(finished); return(2); } DWORD WINAPI ThreadAction_put(LPVOID param) { union packd pa; pa.p = ar; pa.p.action = 'i'; int e,z=5; tr++; int k = 5; while (k) { k = 5; while (tr >= trd && k >=0 ) { if (! iamserv && iamclient) { saddr.sin_port = htons(SERV_PORT); e = sendto(s, pa.buff, sizeof(pa.buff)+1, 0,(PSOCKADDR)&saddr, sizeof(saddr)); }; Sleep(1000); k--; }; if (!alive) Sleep(8000); trd = 0; tr = 0; //k--; if (alive) { k=5; } } return(5); } void drawme(HWND hWnd){ HDC hdc = GetDC(hWnd); DWORD threadID; int x,y; DWORD tm,dig=6844; char str[12] = "0000000000\0"; for (x = 0 ; x <= 5; x++) { dig= ss[x]; for (y = sizeof(str); y>0 ;y--){ tm = dig % 10; dig = int(dig / 10); str[y-1] = 48 + tm; } TextOut(hdc,3, 15 * x,str,sizeof(str)); } ReleaseDC(hWnd, hdc); return; } void initme(){ s = socket(AF_INET,SOCK_DGRAM,IPPROTO_IP); saddr.sin_family=AF_INET; /* Target address is IP */ saddr.sin_port=htons(SERV_PORT); saddr.sin_addr.s_addr = INADDR_ANY; s_cl = socket(AF_INET,SOCK_DGRAM,IPPROTO_IP); caddr.sin_family = AF_INET; caddr.sin_addr.s_addr = INADDR_ANY; //= inet_addr("127.168.86.167"); caddr.sin_port = htons(CLNT_PORT); } void startserv(HWND hWnd) { DWORD threadID; if (bind(s,(struct sockaddr *)(&saddr),sizeof(saddr))!=0){ MessageBox(NULL,"bind at server error","bind",MB_OK); }; finished = CreateEvent(NULL,TRUE,FALSE,NULL); thread = CreateThread( NULL,65536,ThreadAction_serv,(LPVOID)hWnd,CREATE_SUSPENDED,&threadID ); ResumeThread(thread); } bool clientconnect(HWND hWnd) { CloseHandle(finished_cl); DWORD threadID; int rc = bind(s_cl,(struct sockaddr *)(&caddr),sizeof(caddr)); if ( rc != 0 ) { // MessageBox(NULL,"bind at client error,rc != 0 ","bind",MB_OK); // return(false); } finished_cl = CreateEvent(NULL,TRUE,FALSE,NULL); thread_cl = CreateThread( NULL,65536,ThreadAction_cl,(LPVOID)hWnd,CREATE_SUSPENDED,&threadID ); ResumeThread(thread_cl); DWORD threadID2; finished_put = CreateEvent(NULL,TRUE,FALSE,NULL); thread_put = CreateThread( NULL,65536,ThreadAction_put,(LPVOID)hWnd,CREATE_SUSPENDED,&threadID2 ); ResumeThread(thread_put); return(true); } void ServerStop(HWND hWnd) { CloseHandle(finished); CloseHandle(finished_draw); CloseHandle(finished_cl); CloseHandle(finished_put); started = false; closesocket(s); closesocket(s_cl); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_SERVE, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SERVE); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage is only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SERVE); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_SERVE; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex); } // // FUNCTION: InitInstance(HANDLE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable // hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, // CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 200, 256, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; RECT rt; int wmId, wmEvent,rc; TCHAR szHello[MAX_LOADSTRING]; LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); unsigned char i,j, x,y; switch (message) { case WM_CREATE: WSADATA WSAData; rc = WSAStartup(MAKEWORD(1, 1), &WSAData); initme(); if (rc != 0){ MessageBox(NULL, "WSAStartup Error", "Error", MB_OK); return FALSE; } else { return TRUE; } case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; case IDM_EXIT: DestroyWindow(hWnd); break; case IDM_START: if (! iamclient) { iamserv = true; startserv(hWnd); } else { MessageBox(NULL,"I am already client...","tip",MB_OK); } break; case IDM_STOP: iamserv = false; iamclient = false; break; case IDM_CONNECT: if ( ! iamserv && clientconnect(hWnd)) { memset(&ar,0,sizeof(ar)); iamclient = true; } else { MessageBox(NULL,"I am already server...","tip",MB_OK); } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... GetClientRect(hWnd, &rt); EndPaint(hWnd, &ps); break; case WM_DESTROY: ServerStop(hWnd); PostQuitMessage(0); // return FORWARD_WM_DESTROY(hWnd, DefWindowProc); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return DefWindowProc(hWnd, message, wParam, lParam); } // Mesage handler for about box. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; } void err(char * pl) { MessageBox(NULL,get_error_text(WSAGetLastError()), pl,MB_OK); }