ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.06.2019

Просмотров: 105

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Лабораторная работа №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 раза больше.

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


Смотрите также файлы