Добавил:
abhai2013@gmail.com Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lab4

.docx
Скачиваний:
9
Добавлен:
30.06.2018
Размер:
278.93 Кб
Скачать

Лабораторная работа №4

Создание серверных приложений для асинхронного обмена данными на основе модели WSAAsyncSelect

Студента ИТ 14-1 Красовского Абхая

Цель работы: изучить возможности модели WSAAsyncSelect для создания серверных приложений работающих в асинхронном режиме.

Ход работы:

Сервер:

#include "stdafx.h"

#include "Лаб№4_Win32.h"

#define MAX_LOADSTRING 100

// Global Variables:

HINSTANCE hInst; // current instance

TCHAR szTitle[MAX_LOADSTRING]; // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name

HWND hWnd;

// Forward 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);

int APIENTRY _tWinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPTSTR 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_MY4_WIN32, szWindowClass, MAX_LOADSTRING);

MyRegisterClass(hInstance);

// Perform application initialization:

if (!InitInstance(hInstance, nCmdShow))

{

return FALSE;

}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MY4_WIN32);

WSADATA wsd;

if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)

{

MessageBoxA(0, "Can't load WinSock", "Error", 0);

return 0;

}

SOCKET sServerListen, sClient;

struct sockaddr_in localaddr, clientaddr;

HANDLE hThread;

DWORD dwThreadId;

int iSize;

sServerListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

if (sServerListen == SOCKET_ERROR)

{

MessageBoxA(0, "Can't load WinSock", "Error", 0);

return 0;

}

ULONG ulBlock;

ulBlock = 1;

if (ioctlsocket(sServerListen, FIONBIO, &ulBlock) == SOCKET_ERROR)

{

return 0;

}

localaddr.sin_addr.s_addr = htonl(INADDR_ANY);

localaddr.sin_family = AF_INET;

localaddr.sin_port = htons(5050);

if (bind(sServerListen, (struct sockaddr *)&localaddr,

sizeof(localaddr)) == SOCKET_ERROR)

{

MessageBoxA(0, "Can't bind", "Error", 0);

return 1;

}

WSAAsyncSelect(sServerListen, hWnd, WM_USER + 1, FD_ACCEPT);

listen(sServerListen, 4);

// Main message loop:

while (GetMessage(&msg, NULL, 0, 0))

{

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

closesocket(sServerListen);

WSACleanup();

return (int)msg.wParam;

}

ATOM MyRegisterClass(HINSTANCE hInstance) {…}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {…}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

int wmId, wmEvent;

PAINTSTRUCT ps;

HDC hdc;

SOCKET ClientSocket;

int ret;

char szRecvBuff[1024], szSendBuff[1024];

switch (message)

{

case WM_USER + 1:

switch (WSAGETSELECTEVENT(lParam))

{

case FD_ACCEPT:

ClientSocket = accept(wParam, 0, 0);

WSAAsyncSelect(ClientSocket, hWnd, WM_USER + 1, FD_READ | FD_WRITE | FD_CLOSE);

break;

case FD_READ:

ret = recv(wParam, szRecvBuff, 1024, 0);

if (ret == 0)

break;

else if (ret == SOCKET_ERROR)

{

MessageBoxA(0, "Recive data filed", "Error", 0);

break;

}

szRecvBuff[ret] = '\0';

strcpy(szSendBuff, "Command get OK");

ret = send(wParam, szSendBuff, sizeof(szSendBuff), 0);

break;

case FD_WRITE:

//Ready to send data

break;

case FD_CLOSE:

closesocket(wParam);

break;

}

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;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

break;

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);

// TODO: Add any drawing code here...

EndPaint(hWnd, &ps);

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {…}

Клиент:

#include "stdafx.h"

#include "Client.h"

#define MAX_LOADSTRING 100

// Global Variables:

HINSTANCE hInst; // current instance

TCHAR szTitle[MAX_LOADSTRING]; // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name

// Forward 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);

DWORD WINAPI NetThread(LPVOID lpParam)

{

SOCKET sClient;

char szBuffer[1024];

int ret, i;

struct sockaddr_in server;

struct hostent *host = NULL;

char szServerName[1024], szMessage[1024];

strcpy(szMessage, "get");

strcpy(szServerName, "127.0.0.1");

sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (sClient == INVALID_SOCKET)

{

MessageBoxA(0, "Can't create socket", "Error", 0);

return 1;

}

server.sin_family = AF_INET;

server.sin_port = htons(5050);

server.sin_addr.s_addr = inet_addr(szServerName);

if (server.sin_addr.s_addr == INADDR_NONE)

{

host = gethostbyname(szServerName);

if (host == NULL)

{

MessageBoxA(0, "Unable to resolve server", "Error", 0);

return 1;

}

CopyMemory(&server.sin_addr, host->h_addr_list[0],

host->h_length);

}

if (connect(sClient, (struct sockaddr *)&server,

sizeof(server)) == SOCKET_ERROR)

{

MessageBoxA(0, "connect failed", "Error", 0);

return 1;

}

// Send and receive data

ret = send(sClient, szMessage, strlen(szMessage), 0);

if (ret == SOCKET_ERROR)

{

MessageBoxA(0, "send failed", "Error", 0);

}

Sleep(1000);

char szRecvBuff[1024];

ret = recv(sClient, szRecvBuff, 1024, 0);

if (ret == SOCKET_ERROR)

{

MessageBoxA(0, "recv failed", "Error", 0);

}

MessageBoxA(0, szRecvBuff, "Recived data", 0);

closesocket(sClient);

}

int APIENTRY _tWinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPTSTR 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_CLIENT, szWindowClass, MAX_LOADSTRING);

MyRegisterClass(hInstance);

// Perform application initialization:

if (!InitInstance(hInstance, nCmdShow))

{

return FALSE;

}

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CLIENT);

WSADATA wsd;

if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)

{

MessageBoxA(0, "Can't load WinSock", "Error", 0);

return 0;

}

HANDLE hNetThread;

DWORD dwNetThreadId;

hNetThread = CreateThread(NULL, 0, NetThread,

0, 0, &dwNetThreadId);

// Main message loop:

while (GetMessage(&msg, NULL, 0, 0))

{

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

WSACleanup();

return (int)msg.wParam;

}

ATOM MyRegisterClass(HINSTANCE hInstance) {…}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {…}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {…}

LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {…}

Запустим сервер и клиент:

Сделаем мониторинг информации через программу WireShark:

Как видим, на передачу данных с сервера через асинхронные сокеты потратилось 0.000207 секунд, в то время, как на передачу данных через синхронные сокеты, в лабораторной №3, мы потратили на это 0.000865 секунд, примерно в 4 раза больше.

Следовательно, можно сделать вывод, что передача данных через асинхронные сокеты совершается быстрее.

Соседние файлы в предмете Операционные системы и системное программирование