int main(int args, char *argv[]){ int i; sid_widelce = semget(0x200, N, 0600 | IPC_CREAT); sid_dostep = semget(0x201, 1, 0600 | IPC_CREAT); op_dost.sem_num = 0; op_dost.sem_flg = 0; op_wid.sem_flg = 0; semctl(sid_dostep, 0, SETVAL, N-1); for(i=0; i<N; i++){ semctl(sid_widelce, i, SETVAL, 1); filozof(i); } return(EXIT_SUCCESS); }
//*************************************************************************** // main //*************************************************************************** int main(int argc, char *argv[]) { // zpracovani vstupnich argumentu if (((argc > 1) && (!strcmp(argv[1], "/h"))) || (argc > 2)) pomoc(argv[0]); int port = 0; port = (argc > 1) ? atoi(argv[1]) : 5555; if (port == 0) { printf("Spatny format portu\n"); pomoc(argv[0]); } // zachyceni <CTRL-C> signal( SIGINT, catch_sig ); // pri ukonceni programu se zavola clean atexit( clean ); // vytvoreni semaforu int sem = 0; if ((sem = vytvor_semafory()) < 0) { printf("Nelze vytvorit a inicializovat semafory (%d).\n", sem); exit(1); } // vytvoreni sdilene pameti int pamet = 0; if ((pamet = vytvor_pamet()) < 0) { printf("Nelze vytvorit a inicializovat sdilenou pamet (%d).\n", pamet); exit(1); } // vytvoreni socketu int sock_client = 0; int sock_listen = socket(AF_INET, SOCK_STREAM, 0); if (sock_listen == -1) { printf("Nepodarilo se vytvorit socket.\n"); exit(1); } in_addr addr_any = { INADDR_ANY }; sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr = addr_any; // smi socket pouzit cislo portu int opt = 1; if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) printf("Nelze nastavit vlastnosti socketu.\n"); // prirazeni adresy a portu socketu if (bind(sock_listen, (const sockaddr*) &server_addr, sizeof(server_addr)) < 0) { printf("Prirazeni adresy selhalo.\n"); close(sock_listen); exit(1); } // server bude naslouchat na zadanem portu if (listen(sock_listen, 1) < 0) { printf("Nelze naslouchat na zadanem portu.\n"); close(sock_listen); exit(1); } printf("Server spusten a nastaven ...\n"); printf("Zadejte 'quit' pro ukonceni procesu serveru.\n"); int konec = 1; while (konec) { char buf[128]; // mnozina handlu fd_set pro_in; // vynulovani mnoziny FD_ZERO(&pro_in); FD_SET(STDIN_FILENO, &pro_in); // pridani handlu FD_SET(sock_listen, &pro_in); // vybrani handl, na kterem jsou data if (select(sock_listen + 1, &pro_in, NULL, NULL, NULL) < 0) break; // jsou data na stdin? if (FD_ISSET(STDIN_FILENO, &pro_in)) { // nacist je do bufferu read(STDIN_FILENO, buf, sizeof(buf)); } // ceka nejaky kleint na obslouzeni? else if (FD_ISSET(sock_listen, &pro_in)) { sockaddr_in rsa; int rsa_size = sizeof(rsa); // prijmuti noveho spojeni sock_client = accept(sock_listen, (sockaddr*)&rsa, (socklen_t*)&rsa_size); if ( sock_client == -1 ) { printf("Spojeni se nezdarilo...\n"); close(sock_listen); exit(1); } // delka adresy serveru int lsa = sizeof(server_addr); // ziskani vlastni ip getsockname(sock_client, (sockaddr*)&server_addr, (socklen_t*)&lsa); printf("Server sidli na: '%s:%d'\n", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); // ziskani ip klienta getpeername(sock_client, (sockaddr*)&server_addr, (socklen_t*)&lsa); printf("Novy klient prichazi z: '%s:%d'\n", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); char zprava[128]; sprintf(zprava, "Spojeni navazano ...\n"); write(sock_client, zprava, sizeof(zprava)); int zidle = jeVolno(sock_client, 0); if (zidle < 0) // obsazeno { // zavreni spojeni klienta close(sock_client); sock_client = 0; } else { // fork a ulozeni pid potomka klient_pid[klient_cnt] = fork(); if (klient_pid[klient_cnt] == 0) // pokracuje klient { // zavreni spojeni serveru close(sock_listen); return filozof(sock_client, zidle); } else // pokracuje server { // zavreni spojeni klienta close(sock_client); sock_client = 0; klient_cnt++; } } } // byl pozadavek na ukonceni prace serveru? if (!strncasecmp(buf, "quit", 4)) { printf("Server bude ukoncen ...\n"); konec = 0; printf("Cekani na ukonceni vecere vsech filozofu.\n"); // cekani nez se ukonci vsichni klienti (procesy) for (int i = 0; i < klient_cnt; i++) { int s; if (klient_pid[i] > 0) waitpid(klient_pid[i], &s, 0); } close(sock_client); break; } } close(sock_listen); if (uvolni_semafory() < 0) { printf("Nelze rusit semafory.\n"); exit(1); } if (uvolni_pamet() < 0) { printf("Nelze uvolnit pamet.\n"); exit(1); } exit(0); }