//这个函数打开端口SIP_PORT并等待来自本地STCP进程的TCP连接. //在连接建立后, 这个函数从STCP进程处持续接收包含段及其目的节点ID的sendseg_arg_t. //接收的段被封装进数据报(一个段在一个数据报中), 然后使用son_sendpkt发送该报文到下一跳. 下一跳节点ID提取自路由表. //当本地STCP进程断开连接时, 这个函数等待下一个STCP进程的连接. void waitSTCP() { int listenfd; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ perror("error in creating the socket"); exit(2); } int opt = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); clilen = sizeof(cliaddr); memset(&servaddr,0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SIP_PORT); bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); listen(listenfd, LISTENQ); printf("sip running...waiting for STCP connection.\n"); while(1){ stcp_conn = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen); while(1){ int dest_nodeID; seg_t segPtr; if(getsegToSend(stcp_conn, &dest_nodeID, &segPtr)<=0) break; printf("receive from STCP ============================================\n"); printf("dest_nodeID:%d--------\n", dest_nodeID); pthread_mutex_lock(routingtable_mutex); int nextNodeID = routingtable_getnextnode(routingtable, dest_nodeID); printf("get from ROUTE & nextNodeID %d\n",nextNodeID); pthread_mutex_unlock(routingtable_mutex); sip_pkt_t* pkt = malloc(sizeof(sip_pkt_t)); pkt->header.src_nodeID = topology_getMyNodeID(); pkt->header.dest_nodeID = dest_nodeID; pkt->header.length = sizeof(seg_t); pkt->header.type =SIP; memcpy(pkt->data, &segPtr, sizeof(seg_t)); printf("sending pkt to SON============================================\n"); son_sendpkt(nextNodeID, pkt, son_conn); } printf("---------------------------------------------------------------end\n"); } close(listenfd); }
//这个函数打开端口SIP_PORT并等待来自本地STCP进程的TCP连接. //在连接建立后, 这个函数从STCP进程处持续接收包含段及其目的节点ID的sendseg_arg_t. //接收的段被封装进数据报(一个段在一个数据报中), 然后使用son_sendpkt发送该报文到下一跳. 下一跳节点ID提取自路由表. //当本地STCP进程断开连接时, 这个函数等待下一个STCP进程的连接. void waitSTCP() { int sockfd,newsockfd; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; /* First call to socket() function */ if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("waitSIP ERROR opening socket\n"); exit(1); } int on = 1; //port可以立即重新使用 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); //init memset(&serv_addr,0,sizeof(serv_addr)); //settings serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SIP_PORT); /* Now bind the host address using bind() call.*/ if(bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) { perror("SIP-waitSTCP: ERROR on binding\n"); exit(2); } listen(sockfd,10); printf("SIP-WaitSTCP: Begin to wait for STCP Connectins...\n"); int local_nodeID = topology_getMyNodeID(); while(1) { clilen = sizeof(cli_addr); memset(&cli_addr,0,sizeof(cli_addr)); newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr,&clilen); stcp_conn = newsockfd; printf("STCP %d link in..\n",newsockfd); seg_t *buf = (seg_t*)malloc(sizeof(seg_t)); int dest_nodeID = 0; int next_nodeID = 0; while(getsegToSend(stcp_conn,&dest_nodeID,buf) > 0) { printf("SIP-Send: begin to send seg from STCP in a pkt\n"); sip_pkt_t *new_pkt = (sip_pkt_t*)malloc(sizeof(sip_pkt_t)); //settings new_pkt->header.src_nodeID = local_nodeID; new_pkt->header.dest_nodeID = dest_nodeID; new_pkt->header.length = sizeof(stcp_hdr_t) + buf->header.length; new_pkt->header.type = SIP; memcpy(new_pkt->data,buf,new_pkt->header.length); //search for next_nodeID next_nodeID = routingtable_getnextnode(routingtable,dest_nodeID); //send pkt if(son_conn != -1 && son_sendpkt(next_nodeID,new_pkt,son_conn) > 0) printf("SIP send a pkt to SON\n"); else son_conn = -1; printf("SIP-Send: node(%d) sent a pkt to node(%d)",local_nodeID,dest_nodeID); } } printf("SIP-WaitSTCP: Finish waiting for connections...\n"); return ; }
void waitSTCP() { //你需要编写这里的代码. //Create a socket for the socket //If sockfd<0 there was an error in the creation of the socket printf("we are now in waitSTCP!\n"); int slot_num; sip_pkt_t* pkt; int myID = topology_getMyNodeID(); int listenfd, connfd; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror("Problem in creating the socket"); exit(2); } //preparation of the socket address memset(&servaddr,0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SIP_PORT); //bind the socket bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); //listen to the socket by creating a connection queue, then wait for clients listen(listenfd, MAX_NODE_NUM); printf("Server running...waiting for connections.\n"); //accept a connection while(1) { clilen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen); stcp_conn = connfd; printf("Received request...\n"); seg_t* segPtr = (seg_t*)malloc(sizeof(seg_t)); int* dest_nodeID = (int*)malloc(sizeof(int)); while (getsegToSend(stcp_conn, dest_nodeID, segPtr) > 0) { switch(segPtr->header.type) { case 0: printf("SIP get some seg --SYN-- from STCP %d!\n", stcp_conn); break; case 1: printf("SIP get some seg --SYNACK-- from STCP %d!\n", stcp_conn); break; case 2: printf("SIP get some seg --FIN-- from STCP %d!\n", stcp_conn); break; case 3: printf("SIP get some seg --FINACK-- from STCP %d!\n", stcp_conn); break; case 4: printf("SIP get some seg --DATA-- from STCP to send! and the service is %d, and the message is %s\n", ((struct packet_IM*)(segPtr->data))->service, ((struct packet_IM*)(segPtr->data))->message); break; case 5: printf("SIP get some seg --DAYAACK-- from STCP to send!\n"); break; } slot_num = makehash(*dest_nodeID); routingtable_entry_t* ptr = routingtable->hash[slot_num]; while (ptr != NULL) {//寻找是否存在给定目的节点的路由条目 if (*dest_nodeID == ptr->destNodeID) break; ptr = ptr->next; } if (ptr != NULL) {//根据路由表转发报文给下一跳 pkt = (sip_pkt_t*)malloc(sizeof(sip_pkt_t)); pkt->header.src_nodeID = myID; pkt->header.dest_nodeID = *dest_nodeID; pkt->header.length = 24 + segPtr->header.length; pkt->header.type = SIP;//包含在报文中的数据是一个STCP段(包括段首部和数据)——Hobo memcpy(pkt->data, segPtr, pkt->header.length); son_sendpkt(ptr->nextNodeID, pkt, son_conn); printf("sip has send pkt to the son %d %d and the service is %d\n", ptr->nextNodeID, son_conn, ((struct packet_IM*)(segPtr->data))->service); } else { printf("can not get the destnodeID!\n"); //exit(0); } } } printf("we are now off waitSTCP!\n"); return; }