Курсовая: Программа просмотра свободного места на жестком диске сервера
ЧЕЛЯБИНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ОТЧЕТ
о практической работе по дисциплине лСети ЭВМ
Факультет: математический Выполнили: Евсеева М.С.
Переславцев Н.А.
Специальность: прикладная Группа: МП-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);
}