Розробка програмного забезпечення для клієнт-серверних додатків

  • Вид работы:
    Практическое задание
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Украинский
    ,
    Формат файла:
    MS Word
    121,24 Кб
  • Опубликовано:
    2015-05-23
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Розробка програмного забезпечення для клієнт-серверних додатків

Зміст

Лабораторна робота 1. Робота з клієнт-серверними додатками на основі сокетів

Лабораторна робота 2. Створення гри хрестики-нулики на основі сокетів

Лабораторна робота 1. Робота з клієнт-серверними додатками на основі сокетів


Мета роботи: Розробити програму сервер та програму клієнт, де будуть оброблятися запити клієнта сервером.

Завдання:

Розробити програмне забезпечення сервера (прослуховувача сокетів - SockListener) та клієнта, який буде посилати команди (SockCommander).

Виконання завдання:

Завдання виконано у Microsoft Visual Studio 2010 у режимі MFC Application (створення додатку під операційну систему Windows).

Слід сказати, що кожен комп’ютер має свою IP-адресу в мережі. Розглядаючи локальну мережу, приведемо приклад IP-адрес: 192.168.0.100, 127.0.0.1. У даному випадку адреса 127.0.0.1 характеризує локальну адресу комп’ютера. Для простоти за умовчанням будемо налаштовуватись саме на цю адресу.

Наведемо головний код роботи програми сервера та клієнта.

Основні функції програмного коду сервера - проект SockListener.

CSockListenerDlg:: CSockListenerDlg (CWnd* pParent /*=NULL*/)

: CDialog (CSockListenerDlg:: IDD, pParent)

{_hIcon = AfxGetApp () - >LoadIcon (IDR_MAINFRAME);

}CSockListenerDlg:: DoDataExchange (CDataExchange* pDX)

{:: DoDataExchange (pDX);_Control (pDX, IDC_LIST1, m_list1);

}_MESSAGE_MAP (CSockListenerDlg, CDialog)_WM_SYSCOMMAND ()_WM_PAINT ()_WM_QUERYDRAGICON ()_WM_SHOWWINDOW ()_WM_CREATE ()_BN_CLICKED (IDC_EXIT, OnExit)_MESSAGE_MAP ()

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /CSockListenerDlg:: OnInitDialog ()

{:: OnInitDialog ();( (IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);(IDM_ABOUTBOX < 0xF000);* pSysMenu = GetSystemMenu (FALSE);(pSysMenu! = NULL)

{strAboutMenu;. LoadString (IDS_ABOUTBOX);(! strAboutMenu. IsEmpty ())

{>AppendMenu (MF_SEPARATOR);>AppendMenu (MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}(m_hIcon, TRUE); // Set big icon(m_hIcon, FALSE); // Set small icon

// Получение IP(! GetMyIP ()) {("IP не определен", MB_OK|MB_ICONERROR);

}{_MySocket. m_ptrDlg = this;

// Создание и настройка сокета сервера на определенный порт (777)

m_MySocket. Create (PORT,SOCK_STREAM);_MySocket. Listen ();

}TRUE;

}

// Функция получения IP-адресаCSockListenerDlg:: GetMyIP ()

{*hs;ch [4] ={0};csInfo;

:: gethostname ( (LPSTR) (LPCTSTR) m_cshostname, 50);= gethostbyname ( (LPSTR) (LPCTSTR) m_cshostname);(ch, hs->h_addr,4);. Format ("%s %d. %d. %d. %d", m_cshostname,[0], ch [1], ch [2], ch [3]);(IDC_TEXT) - >SetWindowText (csInfo);

return (TRUE);

}

// Получение объекта сокета клиента

void CSockListenerDlg:: ProcessPendingAccept ()

{csSockAddr;csInfo;int nIndex = 0;nSockPort;* pSocket = new CClientSocket (this);

// Открытие соединения(m_MySocket. Accept (*pSocket))

{(pSocket->GetSockName (csSockAddr, nSockPort)) {. Format ("%s: %u - Соединен", csSockAddr, nSockPort);_list1. InsertString (-1, csInfo);

++nIndex;

}

}pSocket;

}

// Закрытие соединенияCSockListenerDlg:: OnCloseConnection (CClientSocket *pSocket)

{

CString csSockAddr;csInfo;int nIndex = 0;nSockPort;(pSocket->GetSockName (csSockAddr, nSockPort)) {. Format ("%s: %u - Разъединен", csSockAddr, nSockPort);_list1. InsertString (-1, csInfo);

}(TRUE);

}

// Прием команды от клиента сервером и ее выполнение

void CSockListenerDlg:: ProcessPendingRead (CClientSocket *pSocket)

{lpBuf [1000] = {0},soob [1000];

// Получение команды>Receive (lpBuf, 1000);

// Выполнение команды(ExecuteCommand (lpBuf, FALSE))

{(soob,"Загружен %s",lpBuf);_list1. InsertString (-1, soob);

}_list1. InsertString (-1, lpBuf);

}

// Выполнение командCSockListenerDlg:: ExecuteCommand (char *cmdstr, int flags)

{rez = WinExec (cmdstr, SW_SHOW);

return rez==33;

}

При запуску програми сервера на екрані з’явиться наступне вікно:


Зверху написано ім’я комп’ютера та його IP-адреса в локальній мережі 192.168.0.100. Крім того у вікні розташований список (клас CListBox), до якого будуть надходити команди клієнта.

І клієнти і сервер повинні бути налаштовані на конкретний порт. У нашому випадку це порт 777.

Далі наведемо основні функції програмного коду клієнту - проект SockCommander.

CSockCommanderDlg:: CSockCommanderDlg (CWnd* pParent /*=NULL*/)

: CDialog (CSockCommanderDlg:: IDD, pParent)

{

// ip по умолчанию (локальная машина)_ip = _T ("127.0.0.1");

// команда по умолчанию_msg = _T ("Введите команду");

m_hIcon = AfxGetApp () - >LoadIcon (IDR_MAINFRAME);

}CSockCommanderDlg:: DoDataExchange (CDataExchange* pDX)

{:: DoDataExchange (pDX);_Text (pDX, IDC_IP, m_ip);_Text (pDX, IDC_MSG, m_msg);_Text (pDX, IDC_PORT, m_port);

}_MESSAGE_MAP (CSockCommanderDlg, CDialog)_WM_SYSCOMMAND ()_WM_PAINT ()_WM_QUERYDRAGICON ()_BN_CLICKED (IDC_CONNECT, OnConnect)_BN_CLICKED (IDC_DISCONNECT, OnDisconnect)_BN_CLICKED (IDC_BUTTON1, &CSockCommanderDlg:: OnBnClickedButton1)_MESSAGE_MAP ()CSockCommanderDlg:: OnInitDialog ()

{:: OnInitDialog ();

// Создание объекта сокета

m_ptrComSocket = new CCommandSocket (this);_nConnected = FALSE;TRUE; // return TRUE unless you set the focus to a control

}

// Соединение клиента с сервером

void CSockCommanderDlg:: OnConnect ()

{status = TRUE;(TRUE);(m_ip. IsEmpty ())

{(MB_ICONQUESTION);(IDC_IP) - >SetFocus ();;

}(m_port. IsEmpty ())

{(5000);(MB_ICONQUESTION) - >SetFocus ();;

}(! m_ptrComSocket->Create (PORT,SOCK_STREAM))

{(MSG_SOCKET_CREAT_FAIL);= FALSE;;

}(! m_ptrComSocket->Connect ( (LPCTSTR) m_ip, atoi (m_port)))

{= FALSE;(MSG_SOCKET_CONCT_FAIL);

return;

}

// Проверка ошибочного соединения(! status)

{_nConnected = FALSE;(IDC_TEXT) - >SetWindowText ("Соединение с "+m_ip+" ошибочно");

}

{_nConnected = TRUE;(IDC_TEXT) - >SetWindowText ("Успешное соединение с "+m_ip);

}

}

// Отправка сообщения серверуCSockCommanderDlg:: OnBnClickedButton1 ()

{(TRUE);(! m_nConnected);(m_msg. IsEmpty ())

{(MB_ICONQUESTION);(IDC_MSG) - >SetFocus ();;

}(! m_ptrComSocket->Send ( (void *) m_msg. GetBuffer (m_msg. GetLength ()),_msg. GetLength ()))

{(MSG_SOCKET_SEND_FAIL);

}

}

// Разъединение соединения

void CSockCommanderDlg:: OnDisconnect ()

{(m_nConnected)

{_ptrComSocket->Close ();_nConnected = FALSE;(IDC_TEXT) - >SetWindowText ("Разъединен с "+m_ip);

}

}

Розглянемо взаємодію та можливості програми сервера та клієнту.

.        Спочатку запускаємо програму сервера - файл SockListener. exe.

2.      Потім запускаємо програму клієнта - файл SockCommander. exe.

.        Виконуємо з’єднання клієнту с сервером.

.        Посилаємо команди серверу.

.        Сервер приймає та обробляє команди.

При запуску програми клієнта на екрані виводиться наступне вікно


У якості IP призначення вказано локальну адресу 127.0.0.1. Порт на який налаштовано сервер 777. Також передбачено введення команд. Унікальність даної розробки в тому, що якщо указати команду на виконання, наприклад: calc, notepad, mspaint тощо - будуть завантажені відповідні додатки, а у вікні сервера виведеться відповідне повідомлення.

Надішлемо дві команди серверу:

.        "Привет всем".

2.      calc.

Після цих команд вікно сервера буду виглядати наступним чином:


Після повідомлення "Загружен calc" на екрані дисплею побачимо калькулятор.


Для завершення роботи клієнту треба від’єднатися від сервера. Для цього необхідно натиснути кнопку "Разъединение".

Лабораторна робота 2. Створення гри хрестики-нулики на основі сокетів

Мета роботи: Розробити клієнт-серверну гру хрестики-нулики.

Завдання:

Розробити програмне забезпечення сервера (client_server_app) та клієнтів (client_app) для реалізації гри хрестики-нулики.

Виконання завдання:

Завдання виконано у Microsoft Visual Studio 2010 у режимі Console.

Наведемо програмний код сервера, головна мета якого створення сонета сервера та прослуховування клієнтів та відправка їм відповідних повідомлень. Сонет створено на основі порту 666.

#include "stdafx. h"

#include <stdio. h>

#include <string. h>

#pragma comment (lib, "wsock32. lib")

#include "winsock2. h"

#include "windows. h"

#include <time. h>

#define MY_PORT 666WINAPI sayHello (LPVOID client_socket);

// Главная функция программыmain ()

{(field,0,sizeof (field)); // никто еще не ходилbuff [1024];("TCP SERVER DEMO\n");(WSAStartup (0x0202, (WSADATA *) &buff [0]))

{("Error WSAStartup %d\n", WSAGetLastError ());- 1;

}mysocket; // ipv4, stream, tcp( (mysocket = socket (AF_INET, SOCK_STREAM, 0)) < 0)

{("Error socket %d\n", WSAGetLastError ());(); // Деиницилизация библиотеки Winsock- 1;

}

sockaddr_in local_addr;_addr. sin_family = AF_INET;_addr. sin_port = htons (MY_PORT);_addr. sin_addr. s_addr = 0;(bind (mysocket, (sockaddr *) &local_addr, sizeof (local_addr)))

{("Error bind %d\n", WSAGetLastError ());

closesocket (mysocket); // закрываем сокет!();- 1;

}(listen (mysocket, 0x100))

{

// Ошибка

printf ("Error listen %d\n", WSAGetLastError ());(mysocket);();- 1;

}cl_count=0;("Waiting for connections. \n");client_socket; // сокет для клиента

sockaddr_in client_addr; // адрес клиента (заполняется системой)

int client_addr_size = sizeof (client_addr);( (client_socket = accept (mysocket, (sockaddr *) &client_addr, \

&client_addr_size)))

{

printf ("%d socket\n", client_socket);

// пытаемся получить имя хоста[cl_count++] =client_socket;*hst;= gethostbyaddr ( (char *) &client_addr. sin_addr. s_addr, 4, AF_INET);

// Вывод сведений о клиенте("+%s [%s] Player %d! \n",

(hst)? hst->h_name: "", inet_ntoa (client_addr. sin_addr),cl_count);

DWORD thID;

// Создание потока с функцией sayHello

CreateThread (NULL, NULL, sayHello, &client_socket, NULL, &thID);

}0;

}

// Функция прослушивания клиента и отправка сообщений в зависимости от кокретных ходов

DWORD WINAPI sayHello (LPVOID client_socket) {my_sock;_sock = ( (SOCKET *) client_socket) [0];player=0;(my_sock==players [0]) player = 1;player = 2;buff [20 * 1024];result [500];

bool k=false;

int win=0;(result,"%d player", player);(my_sock, result, sizeof (result), 0);bytes_recv;( (bytes_recv = recv (my_sock, &buff [0], sizeof (buff), 0)) && bytes_recv! = SOCKET_ERROR)

{(k) count++; // количество ходов в игре[bytes_recv-1] =0;(! strcmp (&buff [0],"Y"))

{(result,"Start!");=true;(player==1) send (players [0], result,strlen (result), 0);

}

{(count>=5)

{(int m = 0; m < 3; m++)

{(field [3*m] == field [3*m+1] && field [3*m+1] == field [3*m+2]) {win=field [3*m];; }if (field [m] == field [m+3] && field [m+3] == field [m+6]) {win=field [m];; }if ( (field [2] == field [4] && field [4] == field [6]) || (field [0] == field [4] && field [4] == field [8])) {win=field [4];; }win=0;

}

}(field [atoi (buff)])

{sprintf (result,"Повторный ход");

send (my_sock, result,sizeof (result), 0);_recv = recv (my_sock, &buff [0], sizeof (buff), 0);[bytes_recv-1] =0;

}(result,"%d", atoi (buff));(player==1) {[atoi (buff)] =1;(players [1], result,strlen (result), 0);

}{[atoi (buff)] =2;(players [0], result,strlen (result), 0);

}(count>=5)

{(int m = 0; m < 3; m++)

{(field [3*m] == field [3*m+1] && field [3*m+1] == field [3*m+2]) {win=field [3*m];; }if (field [m] == field [m+3] && field [m+3] == field [m+6]) {win=field [m];; }if ( (field [2] == field [4] && field [4] == field [6]) || (field [0] == field [4] && field [4] == field [8])) {win=field [4];; }win=0;

}

}

}(win)

{(win==1)

{(result,"Winner is Player 1");

}

{(result,"Winner is Player 2");

}(players [0], result,strlen (result), 0);(players [1], result,strlen (result), 0);

}

}(my_sock);0;

}

сервер сокет клієнт програма

При запуску програми буду виведене наступне вікно, яке буде чекати підключення клієнтів.


Призначення програми клієнт наступні:

.        Встановити з’єднання з сервером.

2.      Малювання поля гри хрестики-нулики для конкретного користувача.

.        Передача параметрів кожного ходу на сервер.

Приведемо код програми клієнту.

#include "stdafx. h"

#include <stdio. h>

#include <string. h>

#pragma comment (lib, "wsock32. lib")

#include <winsock2. h>

#include <locale. h>

#include "fun_console. h"

#define PORT 666_tmain ()

{k=3;pole [9] [2];(int i=0; i<3; i++)

{[i*3] [0] =50;[i*3+1] [0] =60;[i*3+2] [0] =70;

}(int i=0; i<3; i++)

{[i] [1] =k+3;[i+3] [1] =k+9;[i+6] [1] =k+15;

}(0,15);(45,k);("%c", (char) 201);(int i=1; i<30; i++) {("%c", (char) 205);

}("%c\n", (char) 187);(int j=1; j<18; j++)

{(45,++k);("%c", (char) 186);(j%6! =0) {(int i=1; i<30; i++)

{(i%10==0) printf ("%c", (char) 186);printf (" ");

}

} else {(int i=1; i<30; i++) printf ("%c", (char) 205);

}("%c\n", (char) 186);

}(45,++k);("%c", (char) 200);(int i=1; i<30; i++) printf ("%c", (char) 205);("%c\n", (char) 188);(7,0);(0, "rus");buff [1024];(0,0);(WSAStartup (0x202, (WSADATA *) &buff [0]))

{("WSAStart error %d\n", WSAGetLastError ());- 1;

}my_sock;_sock = socket (AF_INET, SOCK_STREAM, 0);(my_sock < 0)

{("Socket () error %d\n", WSAGetLastError ());- 1;

}_in dest_addr;_addr. sin_family = AF_INET;_addr. sin_port = htons (PORT);*hst;SERVERADDR [1024];("Введите IP сервера: ");(&SERVERADDR [0], sizeof (SERVERADDR) - 1, stdin);(inet_addr (SERVERADDR)! = INADDR_NONE)_addr. sin_addr. s_addr = inet_addr (SERVERADDR);

else

{

// попытка получить IP адрес по доменному имени сервера

if (hst = gethostbyname (SERVERADDR))

// hst->h_addr_list содержит не массив адресов,

// а массив указателей на адреса

( (unsigned long *) &dest_addr. sin_addr) [0] =

( (unsigned long **) hst->h_addr_list) [0] [0];

{("Invalid address %s\n", SERVERADDR);(my_sock);();("pause");- 1;

}

}(connect (my_sock, (sockaddr *) &dest_addr, sizeof (dest_addr)))

{("Connect error %d\n", WSAGetLastError ());

return - 1;

}("Соединение успешно установлено\n \

Type quit for quit\n\n");nsize;row=7;

// printf ("Are you ready to play? Y/N\n");= recv (my_sock, &buff [0], sizeof (buff) - 1, 0);[nsize] = 0;("\n%s", buff);player = atoi (buff);key [9] ={1,1,1,1,1,1,1,1,1};

#define Yes "Y"(my_sock, Yes, sizeof (Yes), 0);field [9];(field,0,sizeof (field));( (nsize = recv (my_sock, &buff [0], sizeof (buff) - 1, 0))! = SOCKET_ERROR)

{

// ставим завершающий ноль в конце строки[nsize] = 0;(0,row++);

// выводим на экран("\nS=>C: %s", buff);

if (isdigit ( (unsigned char) buff [0])) {GotoXY (pole [atoi (buff)] [0],pole [atoi (buff)] [1]);(0,15);

(player==1)? printf ("2"): printf ("1");(7,0);[atoi (buff)] = (player==1)? 2: 1;

}(0,row++);

// читаем пользовательский ввод с клавиатуры("\nS<=C: "); fgets (&buff [0], sizeof (buff) - 1, stdin);(! field [atoi (buff)] &&key [atoi (buff)] ==1) {[atoi (buff)] = (player==1)? 1: 2;[atoi (buff)] =2;

}(isdigit ( (unsigned char) buff [0]) && (key [atoi (buff)] ==1||key [atoi (buff)] ==2)) {GotoXY (pole [atoi (buff)] [0],pole [atoi (buff)] [1]);(0,15);

(player==1)? printf ("1"): printf ("2");(7,0);[atoi (buff)] =3;

}(0,row++);

// проверка на "quit"(! strcmp (&buff [0], "quit\n") ||! strcmp (&buff [0], "N\n"))

{

// Корректный выход("Exit. ");(my_sock);

WSACleanup ();0;

}

// передаем строку клиента серверу

send (my_sock, &buff [0], strlen (&buff [0]), 0);

}("Recv error %d\n", WSAGetLastError ());(my_sock);();- 1;

}

При завантаженні програми клієнту буде запропоновано ввести номер ходу від 0 до 8, який буде характеризувати клітинку (зліва направо).

Сервер в свою чергу буде аналізувати ходи кожного з двох користувачів та виведе переможця у разі здобуття перемоги.

Результат роботи програми виглядає наступним чином:


У разі введення 1, вона відобразиться у 2-й комірці.

Похожие работы на - Розробка програмного забезпечення для клієнт-серверних додатків

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!