Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 14

ДИСТРИБУИРАНИ КОМПЈУТЕРСКИ СИСТЕМИ

ВЕЖБИ БР.9 – WINDOWS SOCKET (WINSOCK) КЛИЕНТ – ПРАКТИЧЕН ПРИМЕР

м-р Александар Велинов


ПРАКТИЧЕН ПРИМЕР
#define WIN32_LEAN_AND_MEAN // dokolku e potrebno include za windows.h iako imame winsock2.h
#define _WINSOCK_DEPRECATED_NO_WARNINGS //resavanje vo slucaj na postari verzii

#include <WinSock2.h> //osnovnata biblioteka za rabota so Windows soketi


#include <WS2tcpip.h> //winsock2 ekstenzija za TCP/IP protokolite
#include <iostream> //biblioteka za rabota so osnovnite vlezni i izlezni operacii vo C++
#include <string> //biblioteka za rabota so stringovi

#pragma comment(lib, "Ws2_32.lib") //povrzuvanje so Ws2_32.lib


#define DEFAULT_PORT "27015“ //TCP porta na serverot na koja ke se povrze klientot
#define DEFAULT_BUFFER_LENGTH 512 //definiran bafer

class Client { //klasa za klient


public: //javni metodi
Client(char* servername) //konstruktor na klasata klient
{
szServerName = servername; //ime na serverot
ConnectSocket = INVALID_SOCKET; //soket za povrzuvanje
}
ПРАКТИЧЕН ПРИМЕР
bool Start() { //funkcija za startuvanje na Winsock
WSADATA wsaData; //deklariranje na WSADATA object koj pretstavuva struktura koja gi
//sodrzi osnovnite informacii za implementacijata na Windows sokets

int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); //Inicijaliziranje na Winsock


if(iResult != 0) //Proverka za vratenata vrednost. Ako taa e 0 se pecati poraka za greska
{
printf("WSAStartup failed: %d\n", iResult);//poraka za neuspecna inicijalizacija na Winsock
return false;
}

struct addrinfo*result = NULL, //deklariranje na addrinfo objekt koj ja sodrzi socketaddr


*ptr = NULL,
hints;

ZeroMemory(&hints, sizeof(hints)); //Popolnuva blok od memorija so nuli


hints.ai_family = AF_UNSPEC; //adresnata familija e nespecificirana, moze da bide IPv4 ili IPv6
hints.ai_socktype = SOCK_STREAM; //TCP stream soket
hints.ai_protocol = IPPROTO_TCP; //TCP/IP protokol
ПРАКТИЧЕН ПРИМЕР
iResult = getaddrinfo(szServerName, DEFAULT_PORT, &hints, &result); //Resavanje na
//adresata na serverot i portata
if (iResult != 0) //Ako iResult ne e 0 se pecati deka povikot e neuspesen
{
printf("getaddrinfo failed: %d\n", iResult); //poraka za neuspesen povik
WSACleanup(); //povik do funkcijata WSACleanup za osloboduvanje na resursi
return false;
}
ptr = result;

ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); //Kreiranje


na soket za povrzuvanje so klientot

if (ConnectSocket == INVALID_SOCKET) //Ako soketot e neuspesno kreiran


{
printf("Error at socket(): %d\n", WSAGetLastError()); //se pecati poraka za greska
freeaddrinfo(result); //osloboduvanje na resursi
WSACleanup();
return false;
}
ПРАКТИЧЕН ПРИМЕР
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); //Povrzuvanje so
//serverot

if (iResult == SOCKET_ERROR) //Ako se javi greska


{
closesocket(ConnectSocket); //se zatvora soketot
ConnectSocket = INVALID_SOCKET; //na ConnectSocket mu se dodeluva vrednost INVALID_SOCKET
}

freeaddrinfo(result); //osloboduvanje na adresni informacii

if (ConnectSocket == INVALID_SOCKET) //Ako soketot ima vrednost INVALID_SOCKET


{
printf("Unable to connect to server!\n"); //Se pecati poraka deka ne mozeme da se
povrzeme //na serverot
WSACleanup(); //osloboduvanje na resursi
return false;
}

return true;
};
ПРАКТИЧЕН ПРИМЕР

// Osloboduvanje na resursi
void Stop() {
int iResult = shutdown(ConnectSocket, SD_SEND); //shutdown na soketot, SD_SEND deka
stanuva zbor za soket za klient koj ke parka podatoci na serverot

if (iResult == SOCKET_ERROR) //Ako se javi greska


{
printf("shutdown failed: %d\n", WSAGetLastError()); //Se pecati poraka za greska
}

closesocket(ConnectSocket); //zatvoranje na soketot


WSACleanup(); //osloboduvankje na resursi
};
ПРАКТИЧЕН ПРИМЕР
// Prakanje na poraka na serverot
bool Send(char* szMsg) //Funkcija za prakanje
{

int iResult = send(ConnectSocket, szMsg, strlen(szMsg), 0); //Se koristi send() za


prakanje na poraka so sodrzina smestena vo szMsg koja se prosleduva kako argument na
funkcijata Send()

if (iResult == SOCKET_ERROR) //Ako se javi greska pri prakanje


{
printf("send failed: %d\n", WSAGetLastError()); //se pecati deka prakanjeto e neuspesno
Stop(); //povik do funkcijata Stop() za osloboduvanje na resursi
return false;
}

return true;
};
ПРАКТИЧЕН ПРИМЕР
bool Recv() //funkcija za primanje na poraka od serverot
{
char recvbuf[DEFAULT_BUFFER_LENGTH]; //bafer(niza od karakteri) vo koj se
//smestuva porakata
int iResult = recv(ConnectSocket, recvbuf, DEFAULT_BUFFER_LENGTH, 0); //Povik
do //recv() funkcijata za primanje na poraka od serverot

if (iResult > 0) //Ako iResult e pogolemo od 0


{
char msg[DEFAULT_BUFFER_LENGTH]; //deklariranje na edna nova niza od karakteri
memset(&msg, 0, sizeof(msg));
strncpy(msg, recvbuf, iResult); //Kopiranje na sodrzinata od recvbuf vo msg

printf("Received: %s\n", msg); //pecatenje na porakata koja se parka od serverot

return true;
}

return false;
}
ПРАКТИЧЕН ПРИМЕР

private: //Privatni atributi vo klasata Client


char* szServerName; //ime na serverot
SOCKET ConnectSocket; //soket za povrzuvanje
};
ПРАКТИЧЕН ПРИМЕР
int main(int argc, CHAR* argv[]) //Glavna //funkcija za klientot
{
std::string msg; //deklariranje na string msg(poraka koja se parka do serverot)

Client client("127.0.0.1"); //kreiran object od klasata Client

if (!client.Start()) //Ako povikot do funkcijata Start e neuspesen vrati 1


return 1;

while(true) //Se dodeka e true


{
std::cout << "Send: "; //Pecati poraka za navestuvanje na vnes od strana na korisnikot
std::getline(std::cin, msg); //vnesuvanje na porakata od tastatura

if (msg.compare("close") == 0) // Zatvori ja vrskata koga korisnikot vnesuva “close”


{
break;
}
ПРАКТИЧЕН ПРИМЕР
client.Send((char*)msg.c_str()); //prakanje na porakata koja e vnesena od
//tastatura do serverot
client.Recv(); //Povik do funkcijata Recv za primanje na poraki koi se
prateni //od serverot
}

client.Stop(); //Povik do funkcijata Stop za osloboduvanje na resursi

getchar();
return 0;
}
ПРАКТИЧЕН ПРИМЕР - ИЗЛЕЗ
ЗАДАЧА ЗА ДОМА
• Да се напише код за клиент кој се поврзува на сервер кој се наоѓа локално на
компјутер. За да работи клиентот најпрво потребно е да се напише кодот за
серверот. Како сервер може да се искористи кодот кој е прикачен на курсот.
• Клиентот треба да внесе цел број преку тастатура (1-4). Ако се внесе друг број да се
излезе од програмата.
• Во зависност од изборот на клиентот, на страната на серверот треба да се испечати:
• "Vrati go prviot resurs“
• "Vrati go vtoriot resurs“
• "Vrati go tretiot resurs“
• Или "Vrati go cetvrtiot resurs“
ЗАДАЧА ЗА ДОМА

You might also like