Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 17

Ministerul Educației al Republicii Moldova

Universitatea Tehnică a Moldovei


Departamentul Informatică și Ingineria Sistemelor

RAPORT
Lucrarea de laborator Nr.7 la
Programare de sistem și de reţea

A efectuat:

St. gr. C-171 Davîdic V.

A verificat:

dr., conf.univ. O.Godonoga

Chișinău 2020
Scopul lucrrii:
Implimentarea unui server web simplificat care funcționează doar cu pagini web statice.

Exercitiu 1:

Cod Client:
#include <stdlib.h>
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])


{ int
sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];

//Create socket
sock = socket(AF_INET , SOCK_STREAM ,
0); if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");

server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 4000 );

//Connect to remote server


if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}

puts("Connected\n");

//keep communicating with server


while(1)
{
printf("Enter message : ");
scanf("%s" , message);

//Send some data


if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}

//Receive a reply from the server if(


recv(sock , server_reply , 2000 , 0) < 0)
{
puts("recv failed");
break;
}

puts("Server reply :");


puts(server_reply); system(server_reply);
}

// close(sock);
return 0;
}
Cod Server:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write

int main(int argc , char *argv[])


{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];

//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM ,
0); if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");

//Prepare the sockaddr_in structure


server.sin_family =
AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );

//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");

//Listen
listen(socket_desc , 3);

//Accept and incoming connection


puts("Waiting for incoming connections..."); c
= sizeof(struct sockaddr_in);

//accept connection from an incoming client


client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c); if
(client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");

// char msgCl = recv(client_sock , client_message , 2000 , 0);


// Receive a message from client
while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
{
//Send some data
char *message;
message = "GET /index.html HTTP/1.1\r\n\r\n";
if( send(client_sock , message , strlen(message) , 0) < 0)
{ puts("Send failed");
return 1;
}
puts("Data Send\n");
printf("\n");
//Send the message back to client
// write(client_sock , client_message , strlen(client_message));

if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}

return 0;
}

Exercitiu 2:
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>

#define PORT 4000

/* Citeste cererea clientului. Pune numele fisierului intr-un string.


* Daca sintaxa nu este corecta sau lipsesk retururi la linii * se
trimite -1. In caz contrar functia transmite 0.
* requestFromClient este sirul de 1000 octeti care contine cererea provenita de la client.
* requestSize trebuie sa egala cu 1000 (si nu la lungimea sirului de caractere). */

int parseRequest(char* requestFromClient, int requestSize, char* string, int stringSize)


{
/* charPtr[4] este un tabel cu 4 pointere care poiteaza asupra inceputului sirului, cele 2 spatii
*/
/* ale cererii (cel de dupa GET si cel de dupa numelefisierului) */
/* Pointerul end se va utiliza pentru a pune un '\0' la sfarsitul returului dublu la linie.
*/

char *charPtr[4], *end;

/* Se cauta dublul retur la linie in requestFromClient


* in functie de sisteme de va utiliza \r sau \n (new line, new feed)
* prin conventie in http se utilizeaza ambele \r\n dar in practic e vorba de un singur retur la
linie.
* Pentru a simplifica, aici se cauta doar '\n'.
* Se va plasa un '\0' imediat dupa dublul retur la linie permitand prelucrarea cererii
* casi uilizarea functiilor din biblioteca string.h.
*/

/* Citire pana la dublul retur de linie */


requestFromClient[requestSize-1]='\0';//Permite utilizarea strchr() - atentie, nu merge daca
requestSize indica lungimea sirului de caractere

if( (end=strstr(requestFromClient,"\r\n\r\n"))==NULL) return(9);


*(end+4)='\0';

// Verificarea syntaxei (GET fisier HTTP/1.1)


charPtr[0]=requestFromClient; //Inceputul cererii (GET in principiu)
//Se cauta primul spatiu, codul ascii 0x20 (in hexa), este inceputul numelui fisierului
charPtr[1]=strchr(requestFromClient,' '); if(charPtr[1]==NULL) return(1);
charPtr[2]=strchr(charPtr[1]+1,' '); if(charPtr[2]==NULL) return(2);
charPtr[3]=strchr(charPtr[2]+1,'\r');
if(charPtr[3]==NULL) return(3);
//Se separa sirurile
*charPtr[1]='\0';
*charPtr[2]='\0';
*charPtr[3]='\0';

if(strcmp(charPtr[0],"GET")!=0) return(4);
if(strcmp(charPtr[2]+1,"HTTP/1.1")!=0) return(5);
strncpy(string,charPtr[1]+2,stringSize);//Se decaleasa sirul cu 2 octeti: primul octet este '\0', al
doilea decalaj permite sa retragem "/"

//Daca stringSize nu este suficient de mare, sirul nu contine '\0'. Pentru a verifica et
suficient sa testam string[stringSize-1] care
// trebuie sa fie = '\0' deoarece strncpy unple sirul cu '\0' cand exista loc.
if(string[stringSize-1]!='\0'){
fprintf(stderr,"Erreur parseRequest(): lungimea sirului string nu este suficienta
(stringSize=%d)\n",stringSize);
exit(3);
}

//DEBUG
if( *(charPtr[1]+2) == '\0') fprintf(stderr,"DEBUG-SERVEUR: nomele fisieruui est vid -
\nDEBUG-SERVEUR: - se asociaza fisierul implicit index.html\n");
else fprintf(stderr,"DEBUG-SERVEUR: numele fisierului cerut este %s\n",string); if(

*(charPtr[1]+2) == '\0') strcpy(string,"index.html");

return(0);
}

int main(int argc, char const *argv[])


{
int server_fd, new_socket; long valread;
struct sockaddr_in address; int addrlen
= sizeof(address);

// Only this line has been changed. Everything is same.


char *msg = "HTTP/1.1 400 BAD REQUEST\nContent-Type: text/plain";
char *msg2 = "HTTP/1.1 404 FILE NOT FOUND\nContent-Type: text/plain";

// Creating socket file descriptor


if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("In socket");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr =
INADDR_ANY; address.sin_port = htons(
PORT );

memset(address.sin_zero, '\0', sizeof address.sin_zero);

if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0)


{
perror("In bind");
exit(EXIT_FAILURE
);
}
if (listen(server_fd, 10) < 0)
{
perror("In listen");
exit(EXIT_FAILURE);
}
while(1)
{
printf("waitting\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("In accept");
exit(EXIT_FAILURE);
}

char buffer[30000] = {0};


char buffer1[1000]; char
buffer2[1000]; FILE
*source;
valread = read( new_socket , buffer, 30000);
printf("%s\n",buffer );
int stat = parseRequest(buffer, 30000, buffer1, 1000);

if (stat ==0)
{

source = fopen(buffer1, "r");


if( source == NULL ){
write(new_socket , msg2, strlen(msg2));
printf("no such file\n");
exit(EXIT_FAILURE);

}
else{
while (fgets(buffer2,1000,source) != EOF)
{
puts(buffer2);
write(new_socket , buffer2, strlen(buffer2));
}
}
fclose(source);
}
else
{
write(new_socket , msg, strlen(msg));
}
}
close(new_socket);
return 0; }

Exercitiu 3:
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define IP_PROTOCOL 0
#define PORT_NO 15050
#define NET_BUF_SIZE
32 #define cipherKey 'S'
#define sendrecvflag 0
#define nofile "File Not Found!"

// function to clear buffer void


clearBuf(char* b)
{ int
i;
for (i
= 0; i
<
NET
_
BUF
_
SIZE
; i++)
b[i] =
'\0';
}

// function to encrypt
char Cipher(char ch)
{
return ch ^ cipherKey;
}

// function sending file


int sendFile(FILE* fp, char* buf, int s)
{
int i, len; if (fp ==
NULL) { strcpy(buf,
nofile); len =
strlen(nofile); buf[len]
= EOF; for (i = 0; i <=
len; i++) buf[i] =
Cipher(buf[i]); return
1;
}

char ch, ch2; for (i


= 0; i < s; i++) { ch
= fgetc(fp); ch2 =
Cipher(ch); buf[i]
= ch2; if (ch ==
EOF)
return 1;
}
return 0;
}

// driver code int


main()
{
int sockfd, nBytes; struct sockaddr_in
addr_con; int addrlen = sizeof(addr_con);
addr_con.sin_family = AF_INET;
addr_con.sin_port = htons(PORT_NO);
addr_con.sin_addr.s_addr =
INADDR_ANY; char
net_buf[NET_BUF_SIZE];
FILE* fp;

// socket()
sockfd = socket(AF_INET, SOCK_DGRAM, IP_PROTOCOL);

if (sockfd < 0)
printf("\nfile descriptor not received!!\n");
else
printf("\nfile descriptor %d received\n", sockfd);

// bind()
if (bind(sockfd, (struct sockaddr*)&addr_con, sizeof(addr_con)) == 0)
printf("\nSuccessfully binded!\n"); else
printf("\nBinding Failed!\n");

while (1) {
printf("\nWaiting for file name...\n");

// receive file name


clearBuf(net_buf);

nBytes = recvfrom(sockfd, net_buf,


NET_BUF_SIZE, sendrecvflag,
(struct sockaddr*)&addr_con, &addrlen);
fp = fopen(net_buf, "r");
printf("\nFile Name Received: %s\n", net_buf); if
(fp == NULL)
printf("\nFile open failed!\n");
else
printf("\nFile Successfully opened!\n");

while (1) {

// process if (sendFile(fp, net_buf,


NET_BUF_SIZE)) { sendto(sockfd,
net_buf, NET_BUF_SIZE, sendrecvflag,
(struct sockaddr*)&addr_con, addrlen);
break;
}

// send
sendto(sockfd, net_buf,
NET_BUF_SIZE, sendrecvflag,
(struct sockaddr*)&addr_con, addrlen);
clearBuf(net_buf);
}

printf("~~~~~~~~~~~~~~~~~~\n"); if (fp !=
NULL)
fclose(fp);
}
return 0;
}

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define IP_PROTOCOL 0
#define IP_ADDRESS "127.0.0.1" // localhost
#define PORT_NO 15050
#define NET_BUF_SIZE 32
#define cipherKey 'S'
#define sendrecvflag 0

// function to clear buffer void


clearBuf(char* b)
{
int i;
for (i = 0; i < NET_BUF_SIZE; i+
+) b[i] = '\0';
}

// function for decryption char


Cipher(char ch)
{
return ch ^ cipherKey;
}

// function to receive file int


recvFile(char* buf, int s)
{ int i; char ch; for
(i = 0; i < s; i++) { ch
= buf[i]; ch =
Cipher(ch); if (ch
== EOF) return 1;
else
printf("%c", ch);
}
return 0;
}

// driver code int main()


{
int sockfd, nBytes; struct sockaddr_in addr_con; int
addrlen = sizeof(addr_con); addr_con.sin_family
= AF_INET; addr_con.sin_port = htons(PORT_NO);
addr_con.sin_addr.s_addr = inet_addr(IP_ADDRESS);
char net_buf[NET_BUF_SIZE];
FILE* fp;

// socket()
sockfd = socket(AF_INET,
SOCK_DGRAM, IP_PROTOCOL);

if (sockfd < 0)
printf("\nfile descriptor not received!!\n");
else
printf("\nfile descriptor %d received\n", sockfd);
while (1) {
printf("\nPlease enter file name to receive:\n");
scanf("%s", net_buf); sendto(sockfd, net_buf,
NET_BUF_SIZE,
sendrecvflag, (struct sockaddr*)&addr_con,
addrlen);

printf("\n---------Data Received-----------");

while (1) { //
receive
clearBuf(net_buf);
nBytes = recvfrom(sockfd, net_buf,
NET_BUF_SIZE, sendrecvflag, (struct
sockaddr*)&addr_con, &addrlen);
printf("\n%i", nBytes);
printf("\n%s", net_buf); //
process
if (recvFile(net_buf, NET_BUF_SIZE))
{ break;
}
}
printf("\n--------------------------------\n");
}
return 0; }

Exercitiu 4
Cod Client:
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define BUFLEN 512
#define PORT 9930

void err(char *s)


{
perror(s);
exit(1);
}

int main(int argc, char** argv)


{
struct sockaddr_in serv_addr; int
sockfd, i, slen=sizeof(serv_addr);
char buf[BUFLEN];

if(argc != 2)
{
printf("Usage : %s <Server-IP>\n",argv[0]);
exit(0);
}

if ((sockfd = socket(AF_INET, SOCK_DGRAM,


IPPROTO_UDP))==-1) err("socket");

bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET; serv_addr.sin_port
= htons(PORT);
if (inet_aton(argv[1], &serv_addr.sin_addr)==0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}

while(1)
{
printf("\nEnter data: ");
scanf("%[^\n]",buf);
getchar();
if(strcmp(buf,"exit") == 0)
exit(0);

if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&serv_addr, slen)==-1)


err("sendto()");
}

close(sockfd);
return 0; }
Cod Server:
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define BUFLEN 512
#define PORT 9930

void err(char *str)


{
perror(str);
exit(1);
}

int main(void)
{
struct sockaddr_in my_addr, cli_addr;
int sockfd, i;
socklen_t slen=sizeof(cli_addr);
char buf[BUFLEN];

if ((sockfd = socket(AF_INET, SOCK_DGRAM,


IPPROTO_UDP))==-1) err("socket");
else
printf("Server : Socket() successful\n");

bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET; my_addr.sin_port
= htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))==-1)


err("bind");
else
printf("Server : bind() successful\n");

while(1)
{

if (recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr, &slen)==-1)


err("recvfrom()");
printf("Received packet from %s:%d",inet_ntoa(cli_addr.sin_addr),
ntohs(cli_addr.sin_port), buf);
printf("\nData: %s\n\n", buf);
}

close(sockfd);
return 0; }

Concluzie:

In concluzie pot afirma ca in urma efectuarii acestei lucrari de laborator am


acumulat cunostinte si deprinderi de a lucra cu protocolul special HTTP care este
un protocol de comunicatie responsabil de transferal de hypertext dinte un client si
un server web. Am acumulat experienta noua in modelarea comunicarii server-
client utilizind protocoalele UDP si TCP.

You might also like