Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); this->resize(275, 600); choosew = new ChooseWidget(this); //HeadButton *h = new HeadButton(this); /* list = new QListWidget(this); list->resize(200, 600); FriendWidget *f = new FriendWidget(); QListWidgetItem *i = new QListWidgetItem(); i->setSizeHint(QSize(200, 50)); list->addItem(i); list->setItemWidget(i, f); tree = new QTreeWidget(this); tree->resize(275, 600); tree->move(200, 0); QStringList str; str << QObject::tr("张三"); QTreeWidgetItem *treeitem = new QTreeWidgetItem(tree, str); QTreeWidgetItem *child1 = new QTreeWidgetItem(treeitem, str); treeitem->addChild(child1); */ createTray(); chat_server = new QTcpServer(this); chat_server->listen(QHostAddress::Any, 55554); connect(chat_server, SIGNAL(newConnection()), this, SLOT(receive_connection())); connect(choosew, SIGNAL(to_up_msg(QString,QString)), this, SLOT(send_msg(QString, QString))); connect(choosew, SIGNAL(new_conn(QString, QString)), this, SLOT(new_conn(QString, QString))); connect(this, SIGNAL(rec_msg(QString,QString)), choosew, SLOT(from_up_msg(QString,QString))); }
int main(int argc, char **argv) { struct sockaddr_in server_addr; int ret, max_fd, i; int invalid, sent; fd_set read_tmp, write_tmp; int msg_len; char * msg; queue_l = 0; invalid = 0; sent = 0; if(argc != 3) { printf("Sinstassi: mastermind_client <host> <porta>\n"); exit(1); } //connessione al server FD_ZERO(&read_set); FD_ZERO(&write_set); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; //ipv4 server_addr.sin_port = htons(atoi(argv[2])); ret = inet_pton(AF_INET, argv[1], &server_addr.sin_addr); if(ret==0) { printf("Indirizzo non valido\n"); exit(1); } sd = socket(PF_INET, SOCK_STREAM, 0); if(sd < 0) { printf("Errore creazione socket\n"); exit(1); } ret = fcntl(sd, F_GETFL, 0); //ritorna la lista dei flag fcntl(sd, F_SETFL, ret| O_NONBLOCK); connect(sd, (struct sockaddr *)&server_addr, sizeof(server_addr)); max_fd = sd; FD_SET(sd, &write_set); memset(&player_info.addr, 0, sizeof(player_info.addr)); player_info.addr.sin_family = AF_INET; write_tmp = write_set; select(max_fd+1, NULL, &write_tmp, NULL, NULL); if(FD_ISSET(sd, &write_tmp)) { int ok; socklen_t len = sizeof(ok); getsockopt(sd, SOL_SOCKET, SO_ERROR, (void*)&ok, &len); if(ok!=0) { printf("Errore connessione: %s\n",strerror(ok) ); exit(1); } FD_CLR(sd, &write_set); } FD_SET(sd, &read_set); printf("Connessione al server %s (porta %d) effettuata con successo\n", argv[1], atoi(argv[2])); show_help(); for(;;) { printf("Inserisci il tuo nome: "); fflush(stdout); scanf("%s",player_info.name); flush_in(); printf("Inserisci la porta di ascolto UDP (>1024): "); fflush(stdout); scanf("%hu", &player_info.port); flush_in(); player_info.addr.sin_port = htons(player_info.port); player_info.addr.sin_addr.s_addr = htonl(INADDR_ANY); msg_len = sizeof(player_info.port) + strlen(player_info.name)+1 ; msg = (char*)malloc(msg_len); memset(msg, 0, msg_len); memcpy(msg, &player_info.port, sizeof(player_info.port)); memcpy(msg+sizeof(player_info.port), player_info.name, strlen(player_info.name)); printf("%hu | %s\n", *(unsigned short *) msg, &msg[2]); queue_add(&queue_l, sd, CL_INFO, msg_len, msg ); free(msg); FD_SET(sd, &write_set); sent = 0; for(;;) { read_tmp = read_set; write_tmp = write_set; select(max_fd+1, &read_tmp, &write_tmp, NULL, NULL); for(i=0; i<max_fd+1; i++) { if(FD_ISSET(i, &write_tmp)) { struct queue *p = queue_search(queue_l, sd); ret = send_msg(p); if(p->step == 4) { queue_remove(&queue_l, &p); FD_CLR(sd, &write_set); } } if(FD_ISSET(i, &read_tmp)) { struct queue *p = queue_search(queue_l, sd); if(p==0) p=queue_add(&queue_l, sd, CL_INFO, 0, 0); ret = rec_msg(sd, p); if(ret <= 0) { printf("Server disconnesso\n"); close(sd); exit(1); } if(p->step == 4) { switch(p->flags) { case CL_OK: sent = 1; invalid = 0; break; case CL_INFO: sent = 1; invalid = 1; default: break; } queue_remove(&queue_l, &p); } } } if(sent == 1) break; } if(invalid == 0) { printf("Info inviate correttamente\n"); break; } else { printf("Nome già in uso\n"); } } //risveglio il descrittore relativo alla tastiera FD_SET(fileno(stdin), &read_set); cd = socket(PF_INET, SOCK_DGRAM, 0); //connessione UDP bind(cd, (struct sockaddr*)&player_info.addr, sizeof(player_info.addr)); max_fd = (max_fd < cd)?cd : max_fd; FD_SET(cd, &read_set); cprintf(""); while(1) { fflush(stdout); struct timeval to, *pto; pto = 0; to.tv_sec = 60; to.tv_usec = 0; read_tmp = read_set; write_tmp = write_set; if(command_mode == 0){ pto = &to; } ret = select(max_fd+1, &read_tmp, &write_tmp, NULL, pto); if(ret < 0) { printf("Errore select\n"); cprintf(""); continue; } if (ret == 0){ queue_add(&queue_l, cd, CL_DISC, 0, 0); queue_add(&queue_l, sd, CL_DISC, 0, 0); FD_SET(cd, &write_set); FD_SET(sd, &write_set); command_mode = 1; cprintf("ti sei disconnesso per inattività\n"); continue; } for(i = 0; i < max_fd+1; i++) { if(FD_ISSET(i, &read_tmp)) { if(i == fileno(stdin)) { //nuovi dati dall'utente if (insertingCombination) { read_comb(comb); } else { read_cmd(); } } else if(i == sd) { //nuovi dati dal server int ret; struct queue *p; p = queue_search(queue_l, i); if(p==0){ p = queue_add(&queue_l, i, CL_UNDEF, 0, 0); } ret = rec_msg(sd, p); if(ret <= 0) { printf("Server disconnesso\n"); close(sd); close(cd); exit(0); } if(p->step == 4) { switch(p->flags) { case CL_WHO: printf("%s\n", p->buffer); cprintf(""); queue_remove(&queue_l, &p); break; case CL_CONN: handle_incoming_connect(p); break; case CL_REF: printf("%s ha rifiutato la partita\n", p->buffer); cprintf(""); queue_remove(&queue_l, &p); cprintf(""); break; case CL_ACC: handle_incoming_accept(p); printf("Digita la combinazione segreta: \n"); cprintf(""); fflush(stdout); insertingCombination = 1; isYourTurn = 1; //read_comb(comb); break; case CL_NEC: printf("nessun giocatore con quel nome\n"); cprintf(""); queue_remove(&queue_l, &p); break; case CL_BUSY: printf("giocatore occupato\n"); cprintf(""); queue_remove(&queue_l, &p); break; case CL_DISC: command_mode = 1; insertingCombination = 0; printf("Il tuo avversario si è disconnesso\n"); cprintf(""); queue_remove(&queue_l, &p); break; default: break; } } } else //ricevo dati da un altro client tramite porta UDP { struct queue* p; p = queue_search(queue_l, i); if(p == 0){ p = queue_add(&queue_l, i, CL_UNDEF, 0, 0); } ret = rec_from(i, p, &opponent_info); if(ret < 0) { printf("Client disconnesso, termino la partita\n"); cprintf(""); FD_CLR(i, &write_set); } if(p->step == 4) { switch(p->flags) { case CL_DISC: command_mode = 1; insertingCombination = 0; printf("Il tuo avversario si è disconnesso\n"); cprintf(""); break; case CL_INS: opponentHasInsertedComb = 1; if (insertingCombination == 0) { printf("%s ha inserito la combinazione, la partita può cominciare\n", opponent_info.name); printf("E' il tuo turno\n"); cprintf(""); opponentHasInsertedComb = 0; } FD_CLR(cd, &write_set); break; case CL_COMB: FD_CLR(cd, &write_set); isYourTurn = 1; printf("è il tuo turno\n"); cprintf(""); handle_combination(p->buffer); break; case CL_ANS:{ command_mode = 0; printf("%s\n", p->buffer ); printf("è il turno di %s\n",opponent_info.name ); cprintf(""); FD_CLR(cd, &write_set); break; } case CL_WIN: command_mode = 1; printf("hai vinto!\n"); cprintf(""); FD_CLR(cd, &write_set); queue_add(&queue_l, sd, CL_WIN, 0, 0); FD_SET(sd, &write_set); isYourTurn =0; break; default: break; } queue_remove(&queue_l, &p); } } } if(FD_ISSET(i, &write_tmp)) { if(i == sd) { //server pronto a ricevere struct queue * p; p = queue_search(queue_l, i); ret = send_msg(p); if(ret < 0){ printf("Errore ret send_msg\n"); close(sd); exit(1); } if(p->step == 4) { switch(p->flags) { case CL_QUIT: //close(sd); close(cd); printf("Disconnesso con successo\n"); cprintf(""); exit(0); case CL_ACC: printf("Digita la combinazione segreta: \n"); cprintf(""); fflush(stdout); insertingCombination = 1; isYourTurn = 0; //read_comb(comb); //queue_add(&queue_l, cd, CL_INS, 0, 0); /*p->flags = CL_INS; p->buffer = 0; free(p->buffer); p->length = 0; p->sd = cd; p->step = 1;*/ //FD_SET(cd, &write_set); command_mode = 0; //printf("E' il turno di %s\n", opponent_info.name); break; default: break; } queue_remove(&queue_l, &p); FD_CLR(sd, &write_set); } } else { //client pronto a ricevere struct queue *p; p = queue_search(queue_l, i); ret = send_to(i, p, &opponent_info); if(p->step == 4) { switch(p->flags) { case CL_DISC: break; default: break; } queue_remove(&queue_l, &p); FD_CLR(i, &write_set); } } } } } return 0; }