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

Лабораторная работа по предмету «Программирование»
Информация о работе
  • Тема: Исследование средств обмена, предоставленных библиотекой Winsock
  • Количество скачиваний: 0
  • Тип: Лабораторная работа
  • Предмет: Программирование
  • Количество страниц: 8
  • Язык работы: Русский язык
  • Дата загрузки: 2015-01-20 03:04:38
  • Размер файла: 157.27 кб
Помогла работа? Поделись ссылкой
Ссылка на страницу (выберите нужный вариант)
  • Исследование средств обмена, предоставленных библиотекой Winsock [Электронный ресурс]. – URL: https://www.sesiya.ru/laboratornaya-rabota/programmirovanie/1284-issledovanie-sredstv-obmena-predostavlennyh-bibliotekoy-winsock/ (дата обращения: 23.06.2021).
  • Исследование средств обмена, предоставленных библиотекой Winsock // https://www.sesiya.ru/laboratornaya-rabota/programmirovanie/1284-issledovanie-sredstv-obmena-predostavlennyh-bibliotekoy-winsock/.
Есть ненужная работа?

Добавь её на сайт, помоги студентам и школьникам выполнять работы самостоятельно

добавить работу
Обратиться за помощью в подготовке работы

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

Информация о документе

Документ предоставляется как есть, мы не несем ответственности, за правильность представленной в нём информации. Используя информацию для подготовки своей работы необходимо помнить, что текст работы может быть устаревшим, работа может не пройти проверку на заимствования.

Если Вы являетесь автором текста представленного на данной странице и не хотите чтобы он был размешён на нашем сайте напишите об этом перейдя по ссылке: «Правообладателям»

Можно ли скачать документ с работой

Да, скачать документ можно бесплатно, без регистрации перейдя по ссылке:

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




Кафедра ИС









Лабораторная работа №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для взаимодействия клиент- серверных приложений.
Написаны две программы. Одна моделирует серверное приложение, вторая клиентское.