int main(int argc, char *argv[]) { if (setlocale( LC_ALL, "en_US.utf8" ) == NULL) error("setlocale"); initialize_curses(); unlink_queues(); // delete any stale queues // central data structure contains pointers to various components -- // sockets, message queues, and curses windows. // mqd_t *ob_mq = get_mq_fd(QUEUES[0], O_CREAT | O_RDWR); mqd_t *ib_mq = get_mq_fd(QUEUES[1], O_CREAT | O_RDWR); long *sock_fd = get_socket_fd( SERVER, PORT ); CONFIG config = { .ob_mq = *ob_mq, .ib_mq = *ib_mq, .sk = *sock_fd, .w1 = w1, .w2 = w2, .w3 = w3, }; // define an array of worker threads // void (*workers[]) = { t_socket_line_writer, // reads from message queue, writes to socket t_socket_line_reader, // reads from socket, writes to message queue t_curses_term_writer, // reads from message queue, writes to term t_curses_term_reader, // reads from term, writes to message queue }; // launch threads and wait for them to complete their work // pthread_t T[ LEN( workers ) ]; for (int t = 0; t < LEN(T); t++) { pthread_create(&T[t], NULL, workers[t], &config); } for (int i = 0; i < LEN(T); i++) { pthread_join(T[i], NULL); } // Clean up file handles close(config.sk); mq_close(config.ob_mq); mq_close(config.ib_mq); free(ob_mq); free(ib_mq); free(sock_fd); // clean up curses delwin(w1); delwin(w2); delwin(w3); unlink_queues(); endwin(); return 0; }
int get_client_socket(const char* ip, int port){ int socket_fd; struct in_addr iaddr; struct sockaddr_in address; socket_fd = get_socket_fd(); if(inet_aton(ip, &iaddr)==0){ perror("inet aton failed"); exit(EXIT_FAILURE); } address = get_sockaddr(port, iaddr.s_addr); if(connect(socket_fd, (struct sockaddr*) &address, sizeof(address))<0){ perror("Connect failed"); exit(EXIT_FAILURE); } return socket_fd; }
int init_server_socket(int port){ int socket_fd, result; struct sockaddr_in address; address = get_sockaddr(port, htonl(INADDR_ANY)); socket_fd = get_socket_fd(); result = bind(socket_fd, (struct sockaddr*) &address, sizeof(address)); if(result != 0){ perror("Socket binding failed"); exit(EXIT_FAILURE); } result = listen(socket_fd, SOMAXCONN); if(result != 0){ perror("Socket listening start failed"); exit(EXIT_FAILURE); } return socket_fd; }
int main(int argc, char** argv) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); if (argc != 3) { fprintf(stderr, "Wrong uasge\nUsage: ./forking <port 1> <port 2>\n"); return -1; } int fd1, fd2, acc_fd1, acc_fd2; if ((fd1 = get_socket_fd(argv[1])) == -1) return -1; if ((fd2 = get_socket_fd(argv[2])) == -1) return -1; sock_in receiver1; sock_in receiver2; socklen_t len1 = sizeof(receiver1); socklen_t len2 = sizeof(receiver2); buf_t* buf = buf_new(size); if (buf == NULL) { fprintf(stderr, "Couldn'y allocate memory for buffer\n"); close(fd1); close(fd2); return -1; } while (1) { if ((acc_fd1 = accept(fd1, (struct sockaddr*) &receiver1, &len1)) == -1) { fprintf(stderr, "%s\n", strerror(errno)); close(fd1); close(fd2); return -1; } if ((acc_fd2 = accept(fd2, (struct sockaddr*) &receiver2, &len2)) == -1) { fprintf(stderr, "%s\n", strerror(errno)); close(fd1); close(fd2); return -1; } pid_t process_id = fork(); if (process_id == -1) { fprintf(stderr, "%s\n", strerror(errno)); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); return -1; } if (process_id == 0) { while (1) { ssize_t rhave = buf_fill(acc_fd1, buf, 1); if (rhave == -1) { fprintf(stderr, "Error in reading\n"); buf_free(buf); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); _exit(-1); } if (rhave == 0) _exit(0); ssize_t whave = buf_flush(acc_fd2, buf, buf -> size); if (whave == -1) { fprintf(stderr, "Error in writing\n"); buf_free(buf); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); _exit(-1); } } } process_id = fork(); if (process_id == -1) { fprintf(stderr, "%s\n", strerror(errno)); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); return -1; } if (process_id != 0) { close(acc_fd1); close(acc_fd2); continue; } while (1) { ssize_t rhave = buf_fill(acc_fd2, buf, 1); if (rhave == -1) { fprintf(stderr, "Error in reading\n"); buf_free(buf); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); _exit(-1); } if (rhave == 0) _exit(0); ssize_t whave = buf_flush(acc_fd1, buf, buf -> size); if (whave == -1) { fprintf(stderr, "Error in writing\n"); buf_free(buf); close(fd1); close(fd2); close(acc_fd1); close(acc_fd2); _exit(-1); } } } buf_free(buf); return 0; }
/****************************************************** interpreter関数 ソケット通信でclientからコマンドがきたら、コマンドに応じて返信する *****************************************************/ int interpreter(char *line){ char com[128]; char *ptr; int command_flag=FALSE; int fd = get_socket_fd(); char result[8024]; //結果の文字列領域 int size; int i; //コマンドを切り出す while (*line && whitespace (*line)) line++; ptr = read_token(line, "%s", com); //fprintf(stderr, "recv command: %s\n", com); /******** コマンドに応じて返すデータを変更(ここから) *********/ //生画像データが欲しい if(strcmp(com, "write-rawdata") == 0){ //rawdataを送っている間に画像データが書き変わらないようにロックをかける sema_lock(raw_semaphore); write(fd, rawdata, (process_width*process_height*3)); sema_unlock(raw_semaphore); command_flag = TRUE; } //処理語画像データが欲しい else if(strcmp(com, "write-processdata") == 0){ sema_lock(process_semaphore); write(fd, processdata, (process_width*process_height*3)); sema_unlock(process_semaphore); command_flag = TRUE; } //処理結果(座標等)が欲しい // euslispで解釈しやすいように、()のリスト情報で情報付しておいてやるのがよい // 仕様は自分で決めて、後でclientのeuslisp側のソフトが動くものを作ればいい // ここでは重心位置を返すようにしている else if(strcmp(com, "result") == 0){ size = sprintf(result, "((:centroid"); for(i=0; i<label_num; i++){ size += sprintf(result+size, " #f(%d %d)", (int)linfo[i].xpos,(int)linfo[i].ypos); } size += sprintf(result+size, ")"); size += sprintf(result+size, " (:area"); for(i=0; i<label_num; i++){ size += sprintf(result+size, " %d", linfo[i].area); } size += sprintf(result+size, "))\n"); write(fd, result, size); command_flag = TRUE; } //縦横を返す for vision-viewer else if(strcmp(com, "vision-size")==0){ size = sprintf(result, "(%d %d)\n", process_height, process_width); write(fd, result, size); command_flag = TRUE; } //閾値を変更したい else if(strcmp(com, "color-threshold") == 0){ for(i=0; i<6; i++){ ptr = read_token(ptr, "%d", &rgb_thre[i]); } fprintf(stderr, "change rgb_threshold "); for(i=0; i<6; i++){ fprintf(stderr, "%d ", rgb_thre[i]); } fprintf(stderr, "\n"); command_flag = TRUE; } //閾値を取得したい else if(strcmp(com, "get-color-threshold") == 0){ size = sprintf(result, "#f("); for(i=0; i<6; i++){ size += sprintf(result+size, "%d ", rgb_thre[i]); } size += sprintf(result+size, ")\n"); write(fd, result, size); command_flag = TRUE; } //Labeling個数をセット 引数一つ else if(strcmp(com, "set-displaylabel-num") == 0){ ptr = read_token(ptr, "%d", &display_label_num); fprintf(stderr, "change displaylabelnum %d\n", display_label_num); command_flag = TRUE; } //Labeling個数を取得 else if(strcmp(com, "get-displaylabel-num") == 0){ size = sprintf(result, "%d\n", display_label_num); write(fd, result, size); command_flag = TRUE; } //表示最小面積をセット 引数ひとつ else if(strcmp(com, "set-minarea") == 0){ ptr = read_token(ptr, "%d", &minimum_area); fprintf(stderr, "change minimu area size %d\n", minimum_area); command_flag = TRUE; } //表示最小面積を取得 else if(strcmp(com, "get-minarea") == 0){ size = sprintf(result, "%d\n", minimum_area); write(fd, result, size); command_flag = TRUE; } /******** コマンドに応じて返すデータを変更(ここまで) *********/ //該当しないコマンドがきた場合はその旨を表示 if(command_flag == FALSE){ fprintf(stderr, "No such command %s\n", com); } return 0; }