s
Sesiya.ru

Исследование средств обмена, предоставленных библиотекой Winsock

Информация о работе

Тема
Исследование средств обмена, предоставленных библиотекой Winsock
Тип Лабораторная работа
Предмет Программирование
Количество страниц 8
Язык работы Русский язык
Дата загрузки 2015-01-20 03:04:38
Размер файла 157.27 кб
Количество скачиваний 0
Скидка 15%

Поможем подготовить работу любой сложности

Заполнение заявки не обязывает Вас к заказу


Скачать файл с работой

Помогла работа? Поделись ссылкой

Севастопольский национальный технический университет




Кафедра ИС









Лабораторная работа №6
Исследование средств обмена, предоставленных библиотекой Winsock для взаимодействия клиент - серверных приложений








Выполнил:


Проверил:









Севастополь
2014

ЦЕЛЬ РАБОТЫ

Исследовать средства обмена, предоставленные библиотекой WinSock для взаимодействия клиент - серверных приложений.


ВАРИАНТ ЗАДАНИЯ

Вариант 2.
Реализовать “клиент – серверное” приложение, таким образом, чтоб сервер поддерживал как минимум три соединения. Сервер рассылает сообщения одновременно всем клиентам.


ХОД РАБОТЫ

Текст программы клиентской части


#pragma argsused


#include <vcl.h>
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#pragma hdrstop

#include "fMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
SOCKET my_sock;

//---------------------------------------------------------------------------
__fastcallTfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// ведёмлог
void Log(AnsiString text){
frmMain->memLog->Lines->Add(text);
}
//---------------------------------------------------------------------------
void __fastcallTfrmMain::btnConnectClick(TObject *Sender)
{
char buff[1024];

// инициализациябиблиотеки Winsock
if (WSAStartup(0x202,(WSADATA *)&buff[0])){
Log("ОшибкаWSAStartup "+IntToStr(WSAGetLastError()));
return;
}

Log("Структура WSAStartup заполнена");
// созданиесокета
my_sock = socket(AF_INET,SOCK_STREAM,0);
if (!my_sock){
Log("Ошибка создания сокета
");
return;
}
Log("Сокет создан");

// установка соединения
// заполнение структуры sockaddr_in
// указание адреса и порта сервера
sockaddr_indest_addr;
dest_addr.sin_family=AF_INET;
dest_addr.sin_port=htons(StrToInt(edtPort->Text));
dest_addr.sin_addr.s_addr=inet_addr(edtAddress->Text.c_str());
// пытаемсяустановитьсоединение
Log("Пытаемся установить соединение...");
if (connect(my_sock,(sockaddr *)&dest_addr, sizeof(dest_addr))){
Log("Ошибкаподключения к серверу: "+IntToStr(WSAGetLastError()));
return;
}
// Неблокирующийрежим
unsigned long *argp=(u_long FAR*)malloc(sizeof(u_long));
*argp=1;
ioctlsocket(my_sock,FIONBIO,argp);

Log("Неблокирующийрежимвключён");
Log("Подключение установлено =)");
frmMain->Timer1->Enabled=true;
btnConnect->Enabled = false;
btnDisconnect->Enabled = true;
}


// создание потока для обработки подключившихся клиентов
DWORD WINAPI TestClient(LPVOID client_socket) {
return 0;
}



void Disconnect()
{
if(closesocket(my_sock)!=SOCKET_ERROR){
Log("Закрытиесокета...OK");

if(WSACleanup()!=SOCKET_ERROR){
Log("WSACleanup...OK");
} else {
Log("Ошибка: командаWSACleanupвернулаошибку: "+IntToStr(WSAGetLastError()));
}
} else {
Log("Ошибка: командаclosesocketвернулаошибку: "+IntToStr(WSAGetLastError()));
}

Log("Отключение... OK");
}


void __fastcallTfrmMain::btnDisconnectClick(TObject *Sender)
{
frmMain->Timer1->Enabled=false;
Log("Отключение...");
char buffer[1024];
memset(buffer,0,1024);
strcat(buffer,"#disconn");

if(send(my_sock,buffer,1024,0)!=SOCKET_ERROR){
Log("Посылказапросанаотключение");
}else{
Log("Ошибка: "+IntToStr(WSAGetLastError()));
}

Disconnect();

btnConnect->Enabled = true;
btnDisconnect->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcallTfrmMain::Timer1Timer(TObject *Sender)
{
//char cl_ip[20];
intbytes_recv = 0;
char buff[1024];
AnsiStringrecvBuf;

bytes_recv = recv(my_sock,&buff[0],sizeof(buff),0);

if((bytes_recv) && (bytes_recv != SOCKET_ERROR)){
recvBuf = buff;

if (recvBuf.AnsiCompare("#disconn") == 0) {
Log(">Cерверпринудительноразорвал соединение...");
char mess[1] = "1";
send(my_sock,mess,1,0);
btnConnect->Enabled = true;
btnDisconnect->Enabled = false;
Disconnect();
} else {
Log(">"+recvBuf);
}

memset(buff, 0, sizeof(buff));
}

Application->ProcessMessages();
}
//---------------------------------------------------------------------------

Текстпрограммысервернойчасти

#include <vcl.h>
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#pragma hdrstop

#include "fMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
// созданиесокета
SOCKET mysocket;

// прототипфункции, обслуживающей
// подключившихсяпользователей
DWORD WINAPI TestClient(LPVOID client_socket);

// глобальнаяпеременная - количество
// активных пользователей
intnclients = 0;
charclient_ip[20];
int shut=0;

sockaddr_inclient_addr; // адресклиента

// махколичествоклиентов
SOCKET users[255];


//---------------------------------------------------------------------------
__fastcallTfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// выводинформации
void Log(AnsiString text){
frmMain->memLog->Lines->Add(text);
}// end of
//---------------------------------------------------------------------------
void __fastcallTfrmMain::btnConnectClick(TObject *Sender)
{
char buff[1024];
nclients=0;
// инициализациябиблиотеки Winsock
if (WSAStartup(0x202,(WSADATA *)&buff[0])){
Log("WSAStart error "+IntToStr(WSAGetLastError()));
return;
}

Log("Структура WSAStartup заполнена");
// созданиесокета
mysocket=socket(AF_INET,SOCK_STREAM,0);
if (!mysocket){
Log("Ошибкасозданиясокета: "+IntToStr(WSAGetLastError()));
return;
}
Log("Сокет создан");

// Не блокирующий режим
unsigned long *argp=(u_long FAR*)malloc(sizeof(u_long));
*argp=1;
ioctlsocket(mysocket,FIONBIO,argp);
Log("Неблокирующийрежимвключён");

// связывание сокета с локальным адресом
Log("Связывание сокета с локальным адресом");
sockaddr_inlocal_addr;
local_addr.sin_family=AF_INET;
local_addr.sin_port=htons(StrToInt(edtPort->Text));
local_addr.sin_addr.s_addr=0;

// вызываем bind длясвязывания
if (bind(mysocket,(sockaddr *) &local_addr, sizeof(local_addr))){
Log("Ошибкасвязывания "+IntToStr(WSAGetLastError()));
closesocket(mysocket); // закрываемсокет
WSACleanup();
return;
}

// ожиданиеподключений
if (listen(mysocket,5)){
Log("Ошибкарежимапрослушивания: "+IntToStr(WSAGetLastError()));
closesocket(mysocket);
WSACleanup();
return;
}

Log("Ожиданиеподключений...");
Timer1->Enabled = true;
btnConnect->Enabled = false;
btnDisconnect->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcallTfrmMain::btnDisconnectClick(TObject *Sender)
{
Timer1->Enabled = false;
Log("Отключение...");

char buff[1024];
memset(buff,0,1024);
strcat(buff,"#disconn");

for(int i = 0; i <nclients; i++){
if (send(users[i],buff,1024,0) != SOCKET_ERROR) {
Log("Уведомление об отключении клиенту №"+IntToStr(i+1)+" отправлено");
Sleep(1000);
} else {
Log("Уведомление об отключении клиенту №"+IntToStr(i+1)+" не отправлено");
}
}

if(closesocket(mysocket)!=SOCKET_ERROR){
Log("Сокетзакрыт...OK");
if(WSACleanup()!=SOCKET_ERROR){
Log("WSACleanup...OK");
}else{
Log("Ошибка: командаWSACleanupвернулаошибку: "+IntToStr(WSAGetLastError()));
}
}else{
Log("Ошибка: командаclosesocketвернулаошибку: "+IntToStr(WSAGetLastError()));
}

Log("Отключение...OK");

btnConnect->Enabled = true;
btnDisconnect->Enabled = false;
}


//---------------------------------------------------------------------------
// создание потока для обработки подклю-чившихся клиентов
DWORD WINAPI TestClient(LPVOID client_socket) {
charcl_ip[20];
SOCKET my_sock;
my_sock=((SOCKET *) client_socket)[0];
char buff[1024];
intsh=0;
intbytes_recv;
AnsiStringclientIP(inet_ntoa(client_addr.sin_addr));
// отправляемклиентуприветствие
//send(my_sock,MES,sizeof(MES),0);

// цикл эхо-сервера: прием строки от кли-ента и
// возвращение ее клиенту
while (1){
bytes_recv = recv(my_sock,&buff[0],sizeof(buff),0);

if(bytes_recv)
if(bytes_recv != SOCKET_ERROR){
Log("Отключение: "+clientIP);

if (!strcmp(buff, "#disconn")){
sh=1;
break;
}
memset(buff, 0, sizeof(buff));
//ShowMessage((AnsiString)buff);
}
Application->ProcessMessages();
Sleep(200);
}
if (sh){
// соединение клиентом разорвано
nclients--; // уменьшаем счетчик актив-ных клиентов

Log("Произошло отключение");
if (nclients){
Log(IntToStr(nclients) + " пользователей он-лайн");
}else{
Log("Нет пользователей в он-лайне");
}
// закрываемсокет
closesocket(my_sock);
}
return 0;
}
//---------------------------------------------------------------------------
void __fastcallTfrmMain::Timer1Timer(TObject *Sender)
{
// извлекаем сообщение из очереди
SOCKET client_socket; // сокет для кли-ента

// функции accept необходимо передать размер
// структуры
intclient_addr_size=sizeof(client_addr);

// циклизвлечениязапросов на подклю-чение из очереди
if ((client_socket=accept(mysocket, (sockaddr *) &client_addr, &client_addr_size))!=INVALID_SOCKET){
// увеличиваемсчетчикподключив-шихся клиентов
// вывод сведений о клиенте
Log("Новое подключение: " + (AnsiString)inet_ntoa(client_addr.sin_addr));
//Log(inet_ntoa(client_addr.sin_addr));
nclients++;
if (nclients){
Log(IntToStr(nclients) + " пользователейон-лайн");
DWORD thID;
CreateThread(NULL,NULL,TestClient, &client_socket,NULL,&thID);
users[nclients-1]=client_socket;
}else{
Log("Нет пользователей в он-лайне");
}
}

}
//---------------------------------------------------------------------------


void __fastcallTfrmMain::btnSendClick(TObject *Sender)
{

AnsiString temp = edtMessage->Text;
char buffer[1024];
char * message = temp.c_str();
memset(buffer,0,1024);
strcat(buffer,message);

for(int i=0; i <nclients; i++){
send(users[i],buffer,1024,0);
}
}
//---------------------------------------------------------------------------


void __fastcallTfrmMain::Button1Click(TObject *Sender)
{
memLog->Clear();
}
//---------------------------------------------------------------------------



Рисунок 1 – Начало работы серверной части


Рисунок 2 – Подключение клиентов к серверу


Рисунок 3 – Отправка сервером сообщения


Рисунок 4 – Получение клиентом серверного сообщения


Рисунок 5 – Отключение клиента


ВЫВОДЫ

В ходе выполнения лабораторной работы изучена библиотека WinSockдля взаимодействия клиент- серверных приложений.
Написаны две программы. Одна моделирует серверное приложение, вторая клиентское.

© Copyright 2012-2020, Все права защищены.