// 这个函数连接到节点ID比自己小的所有邻居. // 在所有外出连接都建立后, 返回1, 否则返回-1. int connectNbrs() { int mynode= topology_getMyNodeID(); int mynbrnum = topology_getNbrNum(); int *nbrlist = topology_getNbrArray(); int i=0; for(i=0; i<mynbrnum; i++) { if(nbrlist[i] < mynode) { int sockfd; struct sockaddr_in serv_addr; if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) <0) { perror("Error create socket!\n"); return -1; } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = topology_getfromIDtoIP(nbrlist[i]); serv_addr.sin_port = htons(CONNECTION_PORT); if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))<0) { perror("Error connect\n"); return -1; } nt_addconn(nt, nbrlist[i], sockfd); } } return 1; }
//每个listen_to_neighbor线程持续接收来自一个邻居的报文. 它将接收到的报文转发给SIP进程. //所有的listen_to_neighbor线程都是在到邻居的TCP连接全部建立之后启动的. void* listen_to_neighbor(void* arg) { int i = *(int *)arg; int conn = nt[i].conn; sip_pkt_t* sip_pkt; while(1) { sip_pkt = (sip_pkt_t*)malloc(sizeof(sip_pkt_t)); memset(sip_pkt, 0, sizeof(sip_pkt_t)); if(recvpkt(sip_pkt, conn) > 0) { if(sip_pkt->header.type == SIP ) { printf("receive stcp packet from node %d\n", sip_pkt->header.src_nodeID); } forwardpktToSIP(sip_pkt, sip_conn); } else { //nt[i].conn = -1; wait for next connection close(conn); socklen_t clilen; struct sockaddr_in cli_addr; clilen = sizeof(cli_addr); conn = accept(listenfd, (struct sockaddr*)&cli_addr, &clilen); int node = topology_getNodeIDfromip(&cli_addr.sin_addr); nt_addconn(nt, node, conn); } free(sip_pkt); } }
// 这个线程打开TCP端口CONNECTION_PORT, 等待节点ID比自己大的所有邻居的进入连接, // 在所有进入连接都建立后, 这个线程终止. void* waitNbrs(void* arg) { int nbrNum = topology_getNbrNum(); //你需要编写这里的代码. int total=0; int thisID=topology_getMyNodeID(); for (int i=0;i<nbrNum;i++) if (thisID<nt[i].nodeID) total++; int listenfd=0; struct sockaddr_in servaddr,cliaddr; socklen_t clilen; if ((listenfd=socket(AF_INET, SOCK_STREAM,0))<0) { puts("create socket error!"); } servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(CONNECTION_PORT); const int on = 1; setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); bind(listenfd,(struct sockaddr *)&servaddr, sizeof(servaddr)); listen(listenfd,total); printf("Wait For %d Neighbor Init Success!\n",total); while (total>0) { int conn=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen); int nodeID=topology_getNodeIDfromip(&cliaddr.sin_addr); printf("%d Accept %d connection\n",thisID,nodeID); if (nt_addconn(nt,nodeID,conn)<0) puts("Add Connection Error!"); total--; } return 0; }
// 这个函数连接到节点ID比自己小的所有邻居. // 在所有外出连接都建立后, 返回1, 否则返回-1. int connectNbrs() { //你需要编写这里的代码. int nbrNum = topology_getNbrNum(); int thisID=topology_getMyNodeID(); printf("%d neighbors %d thisID\n",nbrNum,thisID); for (int i=0;i<nbrNum;i++) if (thisID>nt[i].nodeID) { int sockfd; struct sockaddr_in serv_addr; if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0) { perror("socket error"); return -1; } memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(CONNECTION_PORT); memcpy(&serv_addr.sin_addr,&nt[i].nodeIP,sizeof(in_addr_t)); if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0) { perror("connect error"); return -1; } else { printf("%d node connected to %d node\n",thisID,nt[i].nodeID); if (nt_addconn(nt,nt[i].nodeID,sockfd)<0) puts("Add Connection Error!"); } } return 1; }
// 这个函数连接到节点ID比自己小的所有邻居. // 在所有外出连接都建立后, 返回1, 否则返回-1. int connectNbrs() { int nbr_num = topology_getNbrNum(); int local_id = topology_getMyNodeID(); int i; for (i = 0; i < nbr_num; i++){ if (nt[i].nodeID < local_id){ struct sockaddr_in servaddr; int sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(CONNECTION_PORT); servaddr.sin_addr.s_addr = nt[i].nodeIP; if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){ printf("error when connect %d\n", nt[i].nodeID); return -1; } else { if (nt_addconn(nt, nt[i].nodeID, sockfd) == -1) { printf("error when addconn %d\n", nt[i].nodeID); close(sockfd); return -1; } } } } return 1; }
// 这个线程打开TCP端口CONNECTION_PORT, 等待节点ID比自己大的所有邻居的进入连接, // 在所有进入连接都建立后, 这个线程终止. void* waitNbrs(void* arg) { int nbr_num = topology_getNbrNum(); int bigger_node_num = 0; int i; int local_id = topology_getMyNodeID(); for(i = 0; i < nbr_num; i++){ if (nt[i].nodeID > local_id) bigger_node_num++; } struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; int listenfd, connfd; listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(CONNECTION_PORT); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); listen(listenfd, 20); for(;bigger_node_num > 0;){ cliaddr_len = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); printf("receive a connection from %d\n", topology_getNodeIDfromip(&cliaddr.sin_addr)); int client_nodeid = topology_getNodeIDfromip((&cliaddr.sin_addr)); if (client_nodeid > local_id && exist_id(nt, client_nodeid) == true){ if (nt_addconn(nt, client_nodeid, connfd) == -1) printf("error when addconn %d\n", client_nodeid); bigger_node_num--; } else { printf("not wanted, close\n"); close(connfd); } } return 0; }
// 这个线程打开TCP端口CONNECTION_PORT, 等待节点ID比自己大的所有邻居的进入连接, // 在所有进入连接都建立后, 这个线程终止. void* waitNbrs(void* arg) { int connfd; int mynode= topology_getMyNodeID(); int mynbrnum = topology_getNbrNum(); int *nbrlist = topology_getNbrArray(); int listenq=0; int i = 0; for(i=0; i<mynbrnum; i++) { if(nbrlist[i]>mynode) listenq++; } socklen_t clilen; struct sockaddr_in cli_addr, serv_addr; if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Error create socket\n"); exit(-1); } const int one = 1; //port可以立即重新使用 setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one) ); memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(CONNECTION_PORT); if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))<0) { perror("Error bind\n"); exit(-1); } listen(listenfd, MAX_NODE_NUM); clilen = sizeof(cli_addr); for(i=0; i<listenq; i++) { connfd = accept(listenfd, (struct sockaddr *)&cli_addr, &clilen); int node = topology_getNodeIDfromip(&cli_addr.sin_addr); if(nt_addconn(nt, node, connfd) == -1) { printf("Error add!\n"); } printf("Add Node: %d\n", node); } return 0; }
void* waitNbrs(void* arg) { //你需要编写这里的代码. int connfd, listenfd; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; clilen = sizeof(cliaddr); memset(&cliaddr, 0, sizeof(cliaddr)); memset(&servaddr, 0, sizeof(servaddr)); listenfd = socket(AF_INET, SOCK_STREAM, 0); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(CONNECTION_PORT); print_pos(); printf("\tMSG: son listen son at %s:%d\n", inet_ntoa(servaddr.sin_addr), CONNECTION_PORT); const int on = 1; int res; res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(const int)); if (res != 0) { print_pos(); printf("SON ERROR: setsockopt failed\n"); } res = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); if (res != 0) { print_pos(); printf("SON ERROR: bind failed\n"); } res = listen(listenfd, 10); if (res != 0) { print_pos(); printf("SON ERROR: listen failed\n"); } // get my node id int myNodeID = topology_getMyNodeID(); // print_pos(); // printf("\tMSG: MyNodeID = %d\n", myNodeID); if (myNodeID == -1){ print_pos(); printf("ERROR: get my node id failed\n"); exit(1); } // get my neighbor number int nbrNum = topology_getNbrNum(); int *nbr = topology_getNbrArray(); // count connect nbr int t = 0, i = 0; for (; t < nbrNum; t++) if (nbr[t] > myNodeID) i++; // print_pos(); // printf("MSG: I should accept %d connects\n", i); for (; i > 0; i --){ // print_pos(); // printf("MSG: wait son connect...\n"); connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); if (connfd == -1){ print_pos(); printf("MSG: accept failed, retry, errno=%s\n", strerror(errno)); i++; continue; } // get neighbor node id int nbrNodeID = topology_getNodeIDfromip(&cliaddr.sin_addr); // print_pos(); // printf("MSG: accept %s\n", inet_ntoa(cliaddr.sin_addr)); // if (nbrNodeID > myNodeID){ // print_pos(); // printf("\tMSG: setup connection from %d to %d\n", nbrNodeID, myNodeID); int res = nt_addconn(nt, nbrNodeID, connfd); if (res == -1) { printf("ERROR: nt_addconn error\n"); pthread_exit(NULL); } // print_pos(); // printf("MSG: add node=%d, conn=%d\t to nt\n", nbrNodeID, connfd); // } } printf("MSG: son connect neighbors ok\n"); pthread_exit(NULL); }
// 这个函数连接到节点ID比自己小的所有邻居. // 在所有外出连接都建立后, 返回1, 否则返回-1. int connectNbrs() { int sockfd[MAX_NODE_NUM]; int myNodeID = topology_getMyNodeID(); int *nbr = topology_getNbrArray(); int t = topology_getNbrNum(); // print_pos(); // printf("MSG: topology nbr num = %d\n", t); int i; // for (i = 0; i < t; i ++) printf("MSG: nbr item %d\n", nbr[i]); struct sockaddr_in servaddr; // get conn count int conn_ct = 0; for (i = 0; i < t; i ++) { if (nbr[i] < myNodeID) conn_ct++; } // create socket for (i = 0; i < conn_ct; i ++){ sockfd[i] = socket(AF_INET, SOCK_STREAM, 0); if (sockfd[i] < 0){ print_pos(); printf("\tError: create connect Nbrs socket failed\n"); return -1; } } // set up tcp connect int j = 0; for (i = 0; i < t; i ++){ if (nbr[i] < myNodeID) { memset(&servaddr, 0, sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(CONNECTION_PORT); servaddr.sin_addr.s_addr = getIPByNode(nbr[i]); // print_pos(); // printf("MSG: prepare to connect %s:%d, node=%d\n", inet_ntoa(servaddr.sin_addr), CONNECTION_PORT, nbr[i]); // set up connection int result; int retry_ct = 10; do { // print_pos(); // printf("\tMSG: try to connect %d -> %d\n", myNodeID, nbr[i]); result = connect(sockfd[j], (struct sockaddr *)&servaddr, sizeof(struct sockaddr)); if (result == -1){ print_pos(); printf("ERROR: connect %d->%d, failed, retry, errno=%s\n", myNodeID, nbr[i], strerror(errno)); } // else printf("GOOD: connect success\n"); retry_ct --; if (result == -1) sleep(1); } while (result == -1 && retry_ct > 0); // store in neighbor table if (result != -1){ result = nt_addconn(nt, nbr[i], sockfd[j]); if (result == -1){ print_pos(); printf("\tERROR: nt_addconn error\n"); return -1; } printf("MSG: add nt node=%d, conn=%d\n", nbr[i], sockfd[j]); j ++; } else { print_pos(); printf("ERROR: tcp conn failed, retry too many times\n"); return -1; } } } return 1; }
// 这个线程打开TCP端口CONNECTION_PORT, 等待节点ID比自己大的所有邻居的进入连接, // 在所有进入连接都建立后, 这个线程终止. void* waitNbrs(void* arg) { //你需要编写这里的代码. int myid = topology_getMyNodeID(); pid_t pid; socklen_t clilen; int listenfd; //char buf[MAXLINE]; int j = 0; int full = 0; for(j = 0;j<topology_getNbrNum();j++) { if(nt[j].nodeID > topology_getMyNodeID()) { full ++; //printf("nt num :%d %d\n",j,topology_getMyNodeID()); } } struct sockaddr_in cliaddr,servaddr; listenfd = socket(AF_INET,SOCK_STREAM,0); memset(&servaddr, 0, sizeof(struct sockaddr_in)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(CONNECTION_PORT); bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); listen(listenfd,MAX_NODE_NUM);//开始监听 int temp = 0; printf("full:%d",full); for(temp = 0;temp < full;temp++) { clilen = sizeof(cliaddr); int connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen); //close(listenfd); // if((pid = fork()) == 0) //{ // close(listenfd); int neberid = topology_getNodeIDfromip((struct in_addr*)&(cliaddr.sin_addr)); printf("neberid : %d\n",neberid); /*int i = 0; for(i = 0; i < topology_getNbrNum();i++) { if(nt[i].nodeID == neberid) { nt[i].conn = connfd; break; } } if(i == topology_getNbrNum()) { printf("error node !\n"); return 0; }*/ int t = nt_addconn(nt, neberid, connfd); if(t!=1&&t!=0) { printf("error neberid!\n"); } else if(t == 0) { temp--; }else { //return 1; printf("neberid : %d link sucess\n",neberid); } int j= 0; //int full = 1; } return 0; }