black_death_c4t Posted May 29, 2013 Report Posted May 29, 2013 (edited) Cerinta suna cam asa:Se cere un server si unul sau mai multi clienti.Fiecare client trimite catre server un nume de fisier text.Serverul citeste continutul fisierului si ii intoarce clientuluiprimele trei linii in ordine alfabetica din cadrul fisierului.Ma gandeam sa trimit de la client prin pipe o comanda de shell preconstruita de mine , serverul sa o execute si sa trimit inapoi catre client output-ul comenzii executateCe am lucrat eu aiurea pana acu: [C] ----client.c----- /* Se cere un server si unul sau mai multi clienti. Fiec - Pastebin.comE vorba de comunicare intre procese Anyone got any ideas ? I suck at programming . Edited May 29, 2013 by black_death_c4t Quote
black_death_c4t Posted May 29, 2013 Author Report Posted May 29, 2013 F?-l cu boost asio.Limited to C (gcc) . Quote
black_death_c4t Posted May 29, 2013 Author Report Posted May 29, 2013 Ai ajuns in cj si faci so cu boian? )ye -.- could use some help Quote
Nytro Posted May 29, 2013 Report Posted May 29, 2013 F?-l cu boost asio.Cea mai mare prostie, sa folosesti ditamai libraria, mai ales pentru un proiect de 20 de linii de cod. black_death_c4t Deci care e problema? "Se cere un server si unul sau mai multi clienti." - Nu e server pe TCP? Quote
black_death_c4t Posted May 29, 2013 Author Report Posted May 29, 2013 (edited) Cea mai mare prostie, sa folosesti ditamai libraria, mai ales pentru un proiect de 20 de linii de cod. black_death_c4t Deci care e problema? "Se cere un server si unul sau mai multi clienti." - Nu e server pe TCP?Nu , e vorba de comunicare intre procesele aceluiasi sistem fizic , rularea serverului si clientului fiind facuta fiecare intr-un terminal . Am nevoie de o implementare pentru un singur client : clientul trimite la server informatia , serverul o citeste si ii returneaza alta dracie / over.http://www.cs.ubbcluj.ro/~dadi/so1/Lab10/documentation.htmlhttp://www.cs.ubbcluj.ro/~dadi/so1/Lab10/example.htmlhttp://www.cs.ubbcluj.ro/~florin/SO/ExempleSurseDocumentatii/C/PipeFifoMesShmSem/SO_UPipe-H.txt Edited May 29, 2013 by black_death_c4t Quote
M4T3! Posted May 29, 2013 Report Posted May 29, 2013 Un exemplu asemanator:/* * Parintele trimite procesului fiu prin pipe numele unui fisier, * iar procesul fiu va returna catre parinte primele 10 caractere * din fisierul text solicitat. */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <sys/types.h>#include <sys/wait.h>int main(){ int fd[2]; FILE* fp; pid_t childpid; char string[50]; char ch; char readbuffer[50]; pipe(fd); if ((childpid = fork()) == -1) { perror("fork"); exit(1); } if (childpid == 0) //child { close(fd[1]); read(fd[0], readbuffer, sizeof(readbuffer)); fp = fopen(readbuffer, "r"); int i; for (i=0;i<=9;i++) { ch = fgetc(fp); printf("%c",ch); } fclose(fp); } else //parent { printf("Dati calea fisierului: "); gets(string); close(fd[0]); write(fd[1], string, strlen(string)+1); } printf("\n"); return 0;}Sau:Clientul ii transmite serverului un nume de fisier iar serverul intoarce clientului numarul de linii din fisierul respectiv.#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>int main(int _, char**$) //se da ca parametru ruta fisierului in cauza{ int P[2]; pipe(P); write(P[1], $[1], strlen($[1])+1); if (!fork()) { char fbuffer[255]; read(P[0], fbuffer, sizeof(fbuffer)); FILE* f=fopen(fbuffer,"r"); char c;_=1; while (c != EOF)if((c=getc(f))=='\n')_++; fclose(f); write(P[1],&_,sizeof(_)); }else{ wait(0); read(P[0], &_,sizeof(_)); printf("%d\n",_); close(P[0]); close(P[1]); } return 0;} Quote
cmiN Posted May 30, 2013 Report Posted May 30, 2013 (edited) Ai noroc ca nu aveam somn azi-noapte.#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#define SV 1#define CL 2#define BUFL 128#define check(a, !strcmp(a, static inline int str_comp(const void * first, const void * second){ return strcmp(*((char * *)first), *((char * *)second));}void process_file(char * fname, char * lines){ /* open the file, read and sort all lines, then write the first 3 of them to `lines` buffer */ int linesLen = 0; char * * linesVec = NULL; FILE * file = fopen(fname, "r"); while (1) { char line[BUFL]; fgets(line, BUFL, file); if (feof(file)) break; linesVec = realloc(linesVec, ++linesLen * sizeof(char *)); linesVec[linesLen - 1] = malloc((strlen(line) + 1) * sizeof(char)); strcpy(linesVec[linesLen - 1], line); } fclose(file); qsort(linesVec, linesLen, sizeof(char *), str_comp); strcpy(lines, linesVec[0]); strcat(lines, linesVec[1]); strcat(lines, linesVec[2]); for (int i = 0; i < linesLen; ++i) free(linesVec[i]); free(linesVec);}int main(int argc, char * argv[]){ if (argc < 3) { printf("Usage: %s OPTION (NAME...|NAME FILE)\n", argv[0]); puts("Open a server or client using named pipes communication for processing a file.\n\\n\Options:\n\ -s, --server open for serving\n\ -c, --client open for sending\n\\n\Parameters:\n\ NAME path name(s) for FIFO(s)\n\ FILE file path for lines reading"); return 1; } int whoami = 0; if (check(argv[1], "-s") || check(argv[1], "--server")) whoami = SV; else if (check(argv[1], "-c") || check(argv[1], "--client")) whoami = CL; if (whoami == SV) { // make FIFOs int fifoLen = argc - 2; // for input/output char * * fifoIn = malloc(sizeof(char *) * fifoLen); char * * fifoOut = malloc(sizeof(char *) * fifoLen); for (int i = 2; i < 2 + fifoLen; ++i) { int ind = i - 2; int len = sizeof(char) * (strlen(argv[i]) + 2); fifoIn[ind] = malloc(len); fifoOut[ind] = malloc(len); strcpy(fifoIn[ind], argv[i]); strcpy(fifoOut[ind], argv[i]); strcat(fifoIn[ind], "i"); strcat(fifoOut[ind], "o"); // rw-rw-rw- mkfifo(fifoIn[ind], 0666); mkfifo(fifoOut[ind], 0666); } // wait for messages, process them, then send the response for (int i = 0; i < fifoLen; ++i) { pid_t pid = fork(); if (pid == 0) { // the child // open the pipe for reading int fin = open(fifoIn[i], O_RDONLY); char fname[BUFL] = {0}; read(fin, fname, BUFL); close(fin); // read the filename, open and process it printf("Process %s on channel %s\n", fname, argv[i + 2]); char lines[3 * BUFL] = {0}; process_file(fname, lines); // send the lines back to client int fout = open(fifoOut[i], O_WRONLY); write(fout, lines, strlen(lines)); close(fout); return 0; } } // wait processes to finish for (int i = 0; i < fifoLen; ++i) wait(NULL); // free resources for (int i = 0; i < fifoLen; ++i) { unlink(fifoIn[i]); unlink(fifoOut[i]); free(fifoIn[i]); free(fifoOut[i]); } free(fifoIn); free(fifoOut); } else if (whoami == CL) { // prepare pipe names for i/o int len = sizeof(char) * (strlen(argv[2]) + 2); char * fifoIn = malloc(len); char * fifoOut = malloc(len); strcpy(fifoIn, argv[2]); strcat(fifoIn, "i"); strcpy(fifoOut, argv[2]); strcat(fifoOut, "o"); // open server's input for writing int fout = open(fifoIn, O_WRONLY); write(fout, argv[3], strlen(argv[3])); close(fout); // now receive the response int fin = open(fifoOut, O_RDONLY); char lines[3 * BUFL] = {0}; read(fin, lines, 3 * BUFL); close(fin); puts(lines); free(fifoIn); free(fifoOut); } else { fputs("Invalid or no option selected\n", stderr); return 2; } return 0;} Edited May 30, 2013 by cmiN 1 Quote
black_death_c4t Posted May 30, 2013 Author Report Posted May 30, 2013 (edited) meh , se multumeste foarte mult ; intre timp a reusit si creierul meu aproape inutil sa produca ceva aproape folositorhttp://pastebin.com/pTbkEGk6As aprecia daca s-ar uita cineva 2 secunde peste cod , specific la partea in eu transmit prin pipe comanda shell catre server , deoarece , desi fac read(x,x,KKT*sizeof(char)) se citeste doar pana la primul spatiu .Prin KKT ma refer la strlen() de lungimea comenzii initial formate in client ( e undeva pe la 21 de caractere "head -n 3 fisier.txt | sort "). N-am reusit sa descopar de ce se intampla asta asa ca am inlocuit comanda aia mai lunga cu o comanda simpla gen "who" si am verificat daca sistemul client-server functioneaza corespunzator. Edited May 30, 2013 by black_death_c4t Quote
fedorffixxzz Posted June 1, 2013 Report Posted June 1, 2013 (edited) meh , se multumeste foarte mult ; intre timp a reusit si creierul meu aproape inutil sa produca ceva aproape folositor[C] //clientul --- /* Se cere un server si unul sau mai multi clienti. Fiecare cl - Pastebin.comAs aprecia daca s-ar uita cineva 2 secunde peste cod , specific la partea in eu transmit prin pipe comanda shell catre server , deoarece , desi fac read(x,x,KKT*sizeof(char)) se citeste doar pana la primul spatiu .Prin KKT ma refer la strlen() de lungimea comenzii initial formate in client ( e undeva pe la 21 de caractere "head -n 3 fisier.txt | sort "). N-am reusit sa descopar de ce se intampla asta asa ca am inlocuit comanda aia mai lunga cu o comanda simpla gen "who" si am verificat daca sistemul client-server functioneaza corespunzator.Este posibil ca in argv[1] sa ai string termination (\0) sau prioritatea executiilor intre paranteze sa fie gresita?Enuntul problemei pentru acest laborator incepe cu:"Se cere un server si unul sau mai multi clienti"Sunt curios aici cu ce solutii ati veni pentru a preveni deadlock si a face sincronizare intre childs si parent. O alta abordare ar fi un socket (tcp/udp) sau fisier de tip fifo pe sistemul de fisiere. Edited June 1, 2013 by fedorffixxzz Quote