Cześć!
Piszę taki mały i banalnie prosty programik klient - serwer pod linuxem w c i chcę żeby to tak działało: klient wpisuje nazwe pliku [to bedzie kodem towaru] i leci to do serwera, serwer sprawdza czy jest taki plik z nazwa i jesli jest to wraca ta informacja do klienta i klient ewentualnie wyswietla zawartosci tego pliku w swoim terminalu.
Dwa problemy jakie mam:
- nazwa pliku [pobrana przez klienta] jest w tablicy i nie wiem jak tą tablicę wysłać do serwera - tak się domyślam, że o to chodzi
- nie wiem jak z powrotem z serwera przekazać do klienta całą zawartość pliku aby to klient wyświetlił tą zawartość.
Generalnie program to ma być taka mini aplikacja do sprawdzenia cen towarów. Unikalne kody towarów to będą odddzielne pliki [wiem, że to lipna "baza danych" ale nic lepszego nie przychodziło mi do głowy :) ].
Klient:
/* proces klienta */
#include <netdb.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/un.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SIZE sizeof(struct sockaddr_in)
int main()
{
int sockfd;
char rc;
char nazwaPliku[256];
struct sockaddr_in server = {AF_INET, 7000};
/* przeksztalc i zapamietaj adres ip serwera */
server.sin_addr.s_addr = inet_addr("127.0.0.1");
/* ustaw punkt koncowy transportu: */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket call failed");
exit(1);
}
/* polacz gniazdo z adresem serwera: */
if (connect(sockfd, (struct sockaddr *)&server, SIZE) == -1)
{
perror("connect call failed");
exit(1);
}
/* wysylaj i odbieraj informacje od serwera: */
for(rc = '\n'; ; )
{
if (rc == '\n')
printf("********************************************************************\n");
printf("* Podaj kod towaru aby sprawdzić jego nazwe i cenę, q kończy pracę *\n");
printf("********************************************************************\n");
scanf("%s", nazwaPliku);
if (nazwaPliku == 'q')
{
printf("Program konczy prace...\n");
exit(0);
}
send(sockfd, &nazwaPliku, 1, 0);
if (recv(sockfd, &rc, 1, 0) > 0)
printf("%c", rc);
else
{
printf("server has died.\n");
close(sockfd);
exit (1);
}
}
}
Serwer:
/* proces serwera */
#include <netdb.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/un.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SIZE sizeof(struct sockaddr_in)
void catcher(int sig);
int newsockfd;
int main()
{
printf("Serwer jest gotowy aby przyjac zapytanie...\n");
int sockfd;
char nazwaPliku[256];
int jedenZnak;
FILE *wp;
/* zainicjuj gniazdo internetowe z numerem portu 7000
* i adres lokalny, okreslany jako INADDR_ANY
*/
struct sockaddr_in server = {AF_INET, 7000, INADDR_ANY};
static struct sigaction act;
act.sa_handler = catcher;
sigfillset(&(act.sa_mask));
sigaction(SIGPIPE, &act, NULL);
/* ustaw punkt koncowy transportu: */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket call failed");
exit(1);
}
/* zwiaz adres serwera z punktem koncowym */
if (bind(sockfd, (struct sockaddr *)&server, SIZE) == -1)
{
perror("bind call failed");
exit(1);
}
/* zacznij nasluchiwac przychodzacych polaczen */
if (listen(sockfd, 5) == -1)
{
perror("listen call failed");
exit(1);
}
for( ; ; )
{
/* przyjmij polaczenie */
if((newsockfd = accept(sockfd, NULL, NULL)) == -1)
{
perror("accept call failed");
continue;
}
/* utworz proces potomny do pracy z polaczeniem */
if (fork() == 0)
{
/* odbierz dane: */
while (recv(newsockfd, &nazwaPliku, 1, 0) > 0)
{
/* wyszukiwanie pliku o podanej nazwie: */
if (nazwaPliku == 'q')
{
printf("Program konczy prace...\n");
exit(0);
}
if ((wp = fopen(nazwaPliku, "r")) == NULL)
{
printf("Brak towaru w bazie!\n");
exit(1);
}
// pokazuje zawartosc pliku na ekranie:
while ((jedenZnak = getc(wp)) != EOF)
{
putc(jedenZnak, stdout);
}
fclose(wp);
send(newsockfd, &nazwaPliku, 1, 0);
}
/* gdy klient nie wysyla dluzej informacji gniazdo moze byc zamkniete
* i proces potomny zakonczony */
close(newsockfd);
exit (0);
}
/* rodzic nie potrzebuje newsockfd: */
close(newsockfd);
}
}
void catcher (int sig)
{
close(newsockfd);
exit (0);
}