ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.06.2019
Просмотров: 111
Скачиваний: 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 раза больше.
Следовательно, можно сделать вывод, что передача данных через асинхронные сокеты совершается быстрее.