[C] Programy Klient - Serwer z wykorzystaniem FIFO i pamięci współdzielonej

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
damian004
Piegowaty Guziec
Piegowaty Guziec
Posty: 4
Rejestracja: 13 sie 2007, 10:45
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

[C] Programy Klient - Serwer z wykorzystaniem FIFO i pamięci współdzielonej

Post autor: damian004 »

Cześć!

Piszę sobie program na zaliczenie i czuję, że zawiesiłem się przy łapaniu idei. Zgubiłem polecenie, ale chodzi o to, żeby napisać dwa programy: serwer.c, który będzie czekał na dane od klienta, oraz klient.c, który za argument przyjmie nazwę pliku, przekaże serwerowi tę nazwę, serwer otworzy plik i przekaże dane do klienta, klient zwróci zawartość pliku, zamknie się, a serwer będzie czekał dalej. Ten etap mam za sobą, jednak problem leży w tym, że ma to być relacja 1 do wielu, jeden serwer - wielu klientów do obsługi na raz (nie mam nawet jak tego sprawdzić i przetestować, więc przy okazji pomysły mile widziane).

serwer.c:

Kod: Zaznacz cały

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

#define IPC_KEY (t_key) 1992

int main(int argc, char **argv)
{
	int fdin, fdout, fdsize, filesize, pid;
//	int segment_id, segment_size;
//	char *shared_memory;
//	struct shmid_ds buffer;
	
	FILE *file;
	char nazwa[22], *request;
		printf("Server running...\n");
	if((mkfifo("/tmp/toServer", 0666) < 0 || mkfifo("/tmp/toClient", 0666) < 0) 
		|| mkfifo("/tmp/filesizeFIFO", 0666) < 0) {
		printf("Error!\n");
		return -1;
	}
	
//	segment_id = shmget(IPC_KEY, SHMMAX, IPC_CREAT | IPC_EXCL);
//	if (segment_id < 0)
//	{
//		printf("Error!\n");
//		return 1;
//	}
	
	while(1) {
		fdout = open("/tmp/toClient", O_WRONLY, 0);
			printf("Writing opened...\n");
		fdin = open("/tmp/toServer", O_RDONLY, 0);
			printf("Reading opened...\n");
		fdsize = open("/tmp/filesizeFIFO", O_WRONLY, 0);
			printf("Filesizing save opened...\n");
		if(fdin < 0 || fdout < 0) {
			printf("Error!\n");
			return -1;
		}
		fflush(stdout);
		read(fdin, nazwa, 22);
			printf("Filename: %s\nRequest to client: ", nazwa);
		if(strcmp(nazwa, "koniec") == 0) break;
		close(fdin);
		close(fdout);
		close(fdsize);
		pid = fork();
		switch(pid) {
			case -1:
				printf("Error with new fork!\n");
				return -1;
			break;
			case 0:
				if((file = fopen(nazwa, "r+")) == NULL) {
					request = "Brak pliku!";
						printf("%s\n", request); 
					filesize = strlen(request)+1;
					write(fdsize, &filesize, sizeof(int));
					write(fdout, request, filesize);
				} else {
					fseek(file, 0, SEEK_END);
					filesize = ftell(file);
					fseek(file, 0, SEEK_SET);
					request = (char*) malloc(sizeof(char*)*filesize);
					
					fgets(request, filesize, file);
					
					write(fdsize, &filesize, sizeof(int));
					write(fdout, request, filesize);
						printf("%s\n", request);
				}
				return 1;
			break;
			default:
				wait();
		}
	}
	close(fdin);
	close(fdout);
	close(fdsize);
		printf("FIFO closed...\n");
	unlink("/tmp/toClient");
	unlink("/tmp/toServer");
	unlink("/tmp/filesizeFIFO");
		printf("FIFO deleted...\nThanks for using!\n");
	return 0;
}


klient.c:

Kod: Zaznacz cały

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
	int fdin, fdout, fdsize, filesize;
	char *request;
		printf("Client is running...\n");
	fdin = open("/tmp/toClient", O_RDONLY, 0);
		printf("Reading is opened...\n");
	fdout = open("/tmp/toServer", O_WRONLY, 0);
		printf("Writing is opened...\n");
	fdsize = open("/tmp/filesizeFIFO", O_RDONLY, 0);
		printf("Filesizing save opened...\n");
		
	if(fdin < 0 || fdout < 0) {
		printf("Error!\n");
		return -1;
	}
	write(fdout, argv[1], strlen(argv[1])+1);
		printf("File to open: %s\n", argv[1]);
	read(fdsize, &filesize, sizeof(int));
	request = (char*) malloc(sizeof(char*)*filesize);
	read(fdin, request, filesize);
		printf("Request from server: %s\n", request);
	close(fdin);
	close(fdout);
	close(fdsize);
	return 0;
}

Zacząłem próbę z pamięcią współdzieloną, ale nie wiem, czy dwukrotnie tworzyć segment o tym samym kluczu? Jaką wielkość segmentu utworzyć? Co przekazywać via FIFO, dołączać segmenty dopiero w serwerze, czy w poszczególnych klientach? Olać FIFO? Było w poleceniu, raczej nie ominę tego. Chaos mam w głowie :C

dzięki za pomoc o/
Awatar użytkownika
Kiro
Wytworny Kaczor
Wytworny Kaczor
Posty: 340
Rejestracja: 06 lis 2007, 12:38
Płeć: Mężczyzna
Wersja Ubuntu: 14.10
Środowisko graficzne: Unity
Architektura: x86_64

Re: [C] Programy Klient - Serwer z wykorzystaniem FIFO i pamięci współdzielonej

Post autor: Kiro »

Mam wrażenie, że czegoś nie dopowiedziałeś. Ja bym to najprościej na socketach stworzył bez pamięci współdzielonej (bo po co..). Wtedy serwer po odebraniu połączenia robi forka i obsługuje klienta, a główny wątek czeka na dalsze połączenia.
damian004
Piegowaty Guziec
Piegowaty Guziec
Posty: 4
Rejestracja: 13 sie 2007, 10:45
Płeć: Mężczyzna
Wersja Ubuntu: 8.04
Środowisko graficzne: GNOME
Kontakt:

Re: [C] Programy Klient - Serwer z wykorzystaniem FIFO i pamięci współdzielonej

Post autor: damian004 »

nie dodałem, że klient - serwer mają działać lokalnie, w dwóch konsolach, a zadanie ma sprawdzić znajomość takich narzędzi jak kolejki fifo i właśnie pamięć współdzielona ;p
tloszabno
Piegowaty Guziec
Piegowaty Guziec
Posty: 24
Rejestracja: 19 sie 2006, 13:53
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64
Kontakt:

Re: [C] Programy Klient - Serwer z wykorzystaniem FIFO i pamięci współdzielonej

Post autor: tloszabno »

polecam poczytać książki Stevensa ( Programowanie w środowisku systemu unix i programowanie usług sieciowych ) myślę, ze po przeczytaniu odpowiedniego rozdziału powinno pomóc :)
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości