Skocz do zawartości

Program Klient Serwer


snemei

Rekomendowane odpowiedzi

Czesc wam,

 

Mam do napisania program Klient, Serwer pod linuksem w C.

Program generalnie (klient) wysyla liczbe calkowita do (serwera) a serwer ta otrzymana liczbe poteguje i wynik odsyla do klienta.

Nie wiem za bardzo jak sie do tego mam zabrac, moze macie jakies juz gdzies gotowe przyklady na ktorych mozna by sie wzorowac ?

Czy jest ktos w stanie mi pomoc ??

 

Pozdrawiam

gg:9721427

Odnośnik do komentarza
Udostępnij na innych stronach

tak sobei po prostu publikujecie w poscie?

Zazwyczaj "tak sobie" jeśli kody niezbyt długie, ale bywało, że ludziska całkiem długie logi wrzucali, więc proste programy pewnie nie są aż tak długie smile.gif Przyłączam się do prośby.

Pozdr,

W.

Odnośnik do komentarza
Udostępnij na innych stronach

Oto kod

/* Piotr Penar pp5585 */

/* Implemented all tasks */

 

 

#include <limits.h>

#include <signal.h>

#include <string.h>

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <pthread.h>

#include <sys/poll.h>

 

#include "utils.h"

 

#define MAX_HEADER 20480

#define MAX_LINE 2560

#define BSIZ 8192

#define GET 0

#define POST 1

#define TIMEOUT 10*1000 /* TimeOut tme*/

#define DEBUG 0

 

typedef struct passinfo{ /*Stucture used to pass informations to sub-threads */

/* Created to process each request */

int cli;

int method;

char reqhead[MAX_HEADER];

char path[MAX_LINE];

char host[MAX_LINE];

int *stop; /*Pointer to stop variable if stop is not equal 0 */

int portno; /*then while loop from serviceconn doesnt loop any more*/

int count; /* Id of current thread */

int *currentid; /* Id of thread which acctually has right to write to teh client socket */

pthread_mutex_t *mut;

pthread_cond_t *cond;

 

}Passinfo;

 

 

 

char *methods[2] = {"GET", "POST"};

 

int contentlength(char *header);

void parserequest(char *request, int *method, char *host, int *pn, char *path);

void copydata(int from, int to, int len);

void serviceconn(int cli);

void servRequest(Passinfo *p);

 

 

int contentlength(char *header)

{

int len=INT_MAX;

char line[MAX_LINE];

 

if (HTTPheadervalue_case(header, "Content-Length", line))

sscanf(line, "%d", &len);

return len;

}

 

void parserequest(char *request, int *method, char *host, int *pn, char *path)

{

char url[MAX_LINE] = "";

char m[MAX_LINE] = "";

char hostport[MAX_LINE] = "";

char port[MAX_LINE] = "";

int i;

 

sscanf(request, "%[^ ] %[^ ] HTTP/1.1", m, url);

for (i=0; i<2; i++)

if (strcmp(m, methods) == 0)

*method = i;

sscanf(url, "http://%[^\n\r/]%[^\n\r]", hostport, path);

sscanf(hostport, "%[^:]:%[^\n\r]", host, port);

if (*port == '\0')

*pn = 80;

else

*pn = atoi(port);

}

 

void copydata(int from, int to, int len)

{

char tbuff[bSIZ];

int n;

 

while (len > 0) {

if ((n = read(from, tbuff, BSIZ)) <= 0) break;

if (write(to, tbuff, n) < n) break;

len -= n;

}

}

 

void serviceconn(int cli)

{

char reqline[MAX_LINE], temp[MAX_LINE];

char reqhead[MAX_HEADER];

char host[MAX_LINE], path[MAX_LINE];

int method, portno,i=0;

struct pollfd polltemp[1];

Passinfo *p;

int *stop;

int *currentid;

pthread_t t;

 

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

 

/*variable for struct pollfd client socket*/

polltemp[0].fd=cli;

polltemp[0].events=POLLIN; /*Want to check poll for inputs. */

 

currentid = (int *)calloc(1,sizeof(int)); /*Callocing memory for variables used to take care about */

/*threads. Which on has right to write to client socket.*/

stop = (int *)calloc(1,sizeof(int)); /*Pointer pointed space where is stored variable */

/*which can stop loop from serviceconn*/

while(*stop==0){

if(poll(polltemp,1,TIMEOUT)<=0){ /*Function poll if client socket is unused time out after TIMEOUT miliseconds. */

*stop=1;

if(DEBUG==1){

printf("\n**********TIME OUT******************\n");

}

break; /*Close connection immediately */

}

if(TCPreadline(cli, reqline, MAX_LINE)<=0){ /*If request line is empty close connection */

*stop=1;

if(DEBUG==1){

printf("\n*************Asynchro close*******\n");

}

break; /*Close connection immediately. */

}

else{ /* check for the Connection: close in the header */

parserequest(reqline, &method, host, &portno, path);

HTTPreadheader(cli, reqhead, MAX_HEADER);

if(HTTPheadervalue_case(reqhead,"Connection: close",temp)!=0){

*stop=1;

if(DEBUG==1){

printf("\n***********Connection: close!!!*************\n");

}

}

else{ /* If there isn't any reasons to close connection process request */

//printf("%s%s", reqline, reqhead);

HTTPheaderremove_case(reqhead, "Connection");

 

p=(Passinfo *)calloc(1,sizeof(Passinfo)); /*Allocating memory for structure passed to each subthread */

p->cli=cli;

p->method=method;

strcpy(p->host,host);

strcpy(p->reqhead,reqhead);

strcpy(p->path,path);

p->currentid=currentid; /* Pointer pointed to the thread id, har right to write to client socket */

p->portno=portno;

p->mut = &mut;

p->cond = &cond;

p->stop = stop;

p->count=i; /* Subthread ID - passed to subthread */

 

if(method==POST){ /* If method == post dont create thread just process function*/

servRequest(p);

}

else{ /* Creating subthread to process each reaquest (needed to enable pipelining)*/

pthread_create(&t,NULL,(void *)servRequest,(void *)p);

}

i++; /* Thread counter incrementing */

}

}

}

close(cli); /*Closing Client socket */

}

 

void servRequest(Passinfo *p)

{

char resline[MAX_LINE],temp[MAX_LINE];

char reqhead1[MAX_HEADER], reshead[MAX_HEADER];

int srv, v, status,i;

 

 

if ((srv = activesocket(p->host,p->portno)) < 0) { /*Opening server socket for each request (thread) */

sprintf(reshead, "HTTP/1.1 503\r\nContent-Length: 12\r\nConnection: close\r\n\r\nNon-existent");

 

pthread_mutex_lock(p->mut); //LOCKING MUTEX

while(p->count!=*p->currentid){

pthread_cond_wait(p->cond,p->mut); //WAITING FOR CONDITION

}

pthread_mutex_unlock(p->mut); //UNLOCKING MUTEX

 

write(p->cli, reshead, strlen(reshead));

}

else {

sprintf(reqhead1, "%s %s HTTP/1.1\r\n", methods[p->method], p->path);

strcat(reqhead1, "Connection: close\r\n");

strcat(reqhead1, p->reqhead);

printf("\nRequest from socket %d thread %d \n",p->cli,i);

write(srv, reqhead1, strlen(reqhead1));

printf("%s", reqhead1);

 

if (p->method == POST){

if(DEBUG==1){

printf("\nPOST\n");

}

copydata(p->cli, srv, contentlength(p->reqhead));

}

 

pthread_mutex_lock(p->mut); //LOCKING MUTEX

while(p->count!=*p->currentid){

pthread_cond_wait(p->cond,p->mut); //WAITING FOR CONDITION

}

pthread_mutex_unlock(p->mut); //UNLOCKING MUTEX

 

 

TCPreadline(srv, resline, MAX_LINE);

sscanf(resline, "HTTP/1.%d %d ", &v, &status);

HTTPreadheader(srv, reshead, MAX_HEADER);

if(HTTPheadervalue_case(reshead, "Content-Length", temp)==0) { /*If there is no content length in the response header set stop flag to 1 */

if(DEBUG==1){ /*Then function carry on until server will close connection or rach end of buffer */

/*Size of buffer is set to MAX INT if there is no content leghth */

printf("\n****************No Content Lenth**********************\n");

}

(*p->stop)=1; /*Flag to stop while loop from the serviceconn */

}

HTTPheaderremove_case(reshead, "Connection");

write(p->cli, resline, strlen(resline));

printf("%s", resline);

strcpy(resline, "Connection: close\r\n");

write(p->cli, resline, strlen(resline));

write(p->cli, reshead, strlen(reshead));

printf("\nResponse socket %d thread %d\n",p->cli,i);

printf("%s%s", resline, reshead);

if (status != 204 && status != 304){

copydata(srv,p->cli, contentlength(reshead));

}

close(srv); /*Clocing server connection */

 

}

 

pthread_mutex_lock(p->mut); //LOCKING MUTEX

(*p->currentid)++;

pthread_mutex_unlock(p->mut); //UNLOCKING MUTEX

pthread_cond_broadcast(p->cond); //Broadcast.

if(DEBUG==1){

printf("\n££££££££££££££££££££££ thread %d done!!!!",i);

}

free(p);

return;

}

 

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

{

int s = passivesocket(atoi(argv[1]));

pthread_t t;

 

signal(SIGPIPE, SIG_IGN);

while(1) /*I created thread to allow concurent request processing */

pthread_create(&t,NULL,(void *)serviceconn,(void *)acceptconnection(s));

}

 

//i jeszcze utils

 

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <fcntl.h>

#include <netdb.h>

#include <stdio.h>

 

int passivesocket(int portnumber)

{

struct sockaddr_in addr;

int x;

 

x = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);/* Open the socket */

if(x < 0) /* failed ? */

return -1;

memset(&addr, 0, sizeof(addr)); /* Clear the socket address */

addr.sin_family = AF_INET; /* Internet addressing */

addr.sin_addr.s_addr = INADDR_ANY;

addr.sin_port = htons(portnumber); /* 10000 .. 20000 */

if(bind(x, (struct sockaddr*) &addr, sizeof(addr)) < 0)

return -1;

if(listen(x, 5) < 0) /* Accept a queue of 5 */

return -1;

return x;

}

 

int activesocket(char *hostname, int portnumber)

{

struct sockaddr_in addr;

struct hostent *h;

int x;

 

h = gethostbyname(hostname); /* What is the address */

if(h == NULL) { /* hostname not found??*/

fprintf(stderr, "%s: doesn't exist!\n", hostname);

return -1;

}

x = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);/* Open the socket */

if(x < 0) /* failed ? */

return -1;

memset(&addr, 0, sizeof(addr)); /* Clear the socket address */

addr.sin_family = AF_INET; /* Internet addressing */

memcpy(&addr.sin_addr.s_addr, h -> h_addr, sizeof(int)); /*address */

addr.sin_port = htons(portnumber); /* 10000 .. 20000 */

if(connect(x, (struct sockaddr*) &addr, sizeof(addr)) < 0)

return -1;

return x;

}

 

int acceptfrom(int socket, char *client, int size)

{

struct sockaddr_in addr;

struct linger l;

int s, i;

i = sizeof(addr);

s = accept(socket, (struct sockaddr *)&addr, &i);

if(s < 0)

return -1;

l.l_linger = 5;

l.l_onoff = 1;

setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l));

strncpy(client, inet_ntoa(addr.sin_addr), size);

client[size-1] = '\0';

return s;

}

 

int acceptconnection(int socket)

{

char client[40];

return acceptfrom(socket, client, 40);

}

 

int TCPreadline(int s, char *buffer, int size)

{

char *b;

int n, count;

 

b = buffer;

count = 0;

while ((n = read(s, b, 1)) > 0) {

count ++;

if (*b == '\n' || count == size-1)

break;

b ++;

}

if (n < 0) return n;

buffer[count] = '\0';

return count;

}

 

int HTTPreadheader(int s, char *buffer, int size)

{

char *b;

char last;

int n, count;

 

b = buffer;

last = '\n';

count = 0;

while ((n = read(s, b, 1)) > 0) {

count ++;

if ((*b == '\n' && last == '\n') || count == size-1)

break;

if (*b != '\r') last = *b;

b ++;

}

if (n < 0)

return n;

buffer[count] = '\0';

return count;

}

 

int HTTPheadervalue(char *header, char *key, char *value)

{

char *b = header;

int i;

 

while (1) {

b = strstr(b, key);

if (b == NULL) return 0;

if (b == header || *(b-1) == '\r' || *(b-1) == '\n') break;

b++;

}

b += strlen(key)+1;

while (*b == ' ')

b++;

i = strcspn(b, "\n\r");

strncpy(value, b, i);

value = '\0';

return 1;

}

 

void HTTPheaderremove(char *header, char *key)

{

char *b = header;

char *nextline;

 

while (1) {

b = strstr(b, key);

if (b == NULL) return;

if (b == header || *(b-1) == '\r' || *(b-1) == '\n') break;

b++;

}

nextline = b;

while (*nextline != '\n')

nextline++;

nextline++;

while (*nextline != '\0')

*b++ = *nextline++;

*b = '\0';

}

 

char *strstr_case(char *p, char *key)

{

int len = strlen(key);

 

while (*p != '\0')

if (strncasecmp(p, key, len) == 0)

return p;

else

p++;

return NULL;

}

 

int HTTPheadervalue_case(char *header, char *key, char *value)

{

char *b = header;

int i;

 

while (1) {

b = strstr_case(b, key);

if (b == NULL) return 0;

if (b == header || *(b-1) == '\r' || *(b-1) == '\n') break;

b++;

}

b += strlen(key)+1;

while (*b == ' ')

b++;

i = strcspn(b, "\n\r");

strncpy(value, b, i);

value = '\0';

return 1;

}

 

void HTTPheaderremove_case(char *header, char *key)

{

char *b = header;

char *nextline;

 

while (1) {

b = strstr_case(b, key);

if (b == NULL) return;

if (b == header || *(b-1) == '\r' || *(b-1) == '\n') break;

b++;

}

nextline = b;

while (*nextline != '\n')

nextline++;

nextline++;

while (*nextline != '\0')

*b++ = *nextline++;

*b = '\0';

}

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...