Пример #1
0
void *seghandler(void* arg) {	
	int i;
	seg_t* seg=malloc(sizeof(seg_t));
	client_tcb_t *t=NULL;
	while(1)
	{
		i=sip_recvseg(son_conn,seg);
		if(i<0)continue;	//this seg lost
		printf("receive a seg dest:%d  type  ack: %d\n",seg->header.dest_port,seg->header.ack_num);
		t=NULL;
		for(i=0;i<MAX_TRANSPORT_CONNECTIONS;i++)
		{
			if(TCBTable[i]!=NULL&&TCBTable[i]->server_portNum==seg->header.src_port&&TCBTable[i]->client_portNum==seg->header.dest_port){
				t=TCBTable[i];
				break;
			}
		}
		if(t==NULL)continue;
		switch(t->state)
		{
			case CLOSED:break;
			case SYNSENT:if(seg->header.ack_num==t->next_seqNum&&seg->header.type==SYNACK)
							 t->state=CONNECTED;
						 break;
			case CONNECTED:break;
			case FINWAIT:if(seg->header.ack_num==t->next_seqNum&&seg->header.type==FINACK)
							 t->state=CLOSED;
		}
	}
	return 0;
}
Пример #2
0
void *seghandler(void* arg) {
	int rslt;
	seg_t* seg=(seg_t *)malloc(sizeof(seg_t));
	while(1)
	{
		memset(seg, 0, sizeof(seg_t));
		rslt=sip_recvseg(connection, seg);
		if(rslt==0) {
			int i = 0;
			for(i=0;i<MAX_TRANSPORT_CONNECTIONS;i++)
			{
				if(client_tcb_table[i]!=NULL){
					if(client_tcb_table[i]->client_portNum == seg->header.dest_port){
						//printf("======= i = %d ========\n", i);
						break;
					}
				}
			}
			if(i == MAX_TRANSPORT_CONNECTIONS) {
				printf("TCB ERROR!\n");
			}
			switch(client_tcb_table[i]-> state)	{
				case CLOSED: {
					printf("State: CLOSED\n");
					printf("---------------------------------\n");
				} break;
									
				case SYNSENT: {
					printf("State: SYNSENT\n");
					printf("---------------------------------\n");
					if(seg->header.type==SYNACK){
						client_tcb_table[i]->state=CONNECTED;
					}
				} break;
				case CONNECTED: {
					printf("State: CONNECTED\n");
					printf("---------------------------------\n");
				} break;
				case FINWAIT: {
					printf("State: FINWAIT\n");
					printf("---------------------------------\n");
					if(seg->header.type==FINACK)
						client_tcb_table[i]->state=CLOSED;
				} break;
				default: break;
			}
		}
		else if(rslt < 0){
			printf("Recv Error!\n");
			break;
		}
   }
   return 0;
}
Пример #3
0
void *seghandler(void* arg) {

	seg_t recvbuffer;
	while(1)
	{
		int temp = sip_recvseg(tcp_conn,&recvbuffer);
	if (temp == 0)
	{
		//printf("recv buffer\n");
		handle(&recvbuffer);
	}else
	{
		if (temp == 2)
		{
			printf("RECV ERROR!\n");
			exit(0);
		}else;
	}
	}

  return 0;
}
Пример #4
0
// 这是由stcp_server_init()启动的线程. 它处理所有来自客户端的进入数据. seghandler被设计为一个调用sip_recvseg()的无穷循环, 
// 如果sip_recvseg()失败, 则说明重叠网络连接已关闭, 线程将终止. 根据STCP段到达时连接所处的状态, 可以采取不同的动作.
// 请查看服务端FSM以了解更多细节.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
void* seghandler(void* arg)
{
	server_tcb_t *recv_tcb = NULL;
	seg_t *seg = (seg_t *)malloc(sizeof(seg_t));
	seg_t *seg_ack = (seg_t *)malloc(sizeof(seg_t));
	while(1) {
		recv_tcb = NULL;
		memset(seg, 0, sizeof(seg_t));
		memset(seg_ack, 0, sizeof(seg_t));
		int n = sip_recvseg(global_conn, seg);
		if(n == 2) {
			//printf("Seg lost!\n");
			printf("---------------------------------\n");
			continue;
		}
		else if(n == 0) {
			//judge checksum first!
			if(checkchecksum(seg) == -1) {
				printf("Error checksum!\n");
				printf("---------------------------------\n");
				continue;
			}
			//printf("Receive a seg!\n");
			int i = 0;
			int port = seg->header.dest_port;
			for(i=0; i<MAX_TRANSPORT_CONNECTIONS; i++) {
				if(server_tcb_table[i]->server_portNum == port)
					break;
			}
			recv_tcb = server_tcb_table[i];
			if(recv_tcb == NULL || i == MAX_TRANSPORT_CONNECTIONS) {
				perror("Server tcb table error!\n");
				exit(-1);
			}
			switch(recv_tcb->state) {
				case CLOSED: {
					printf("State: CLOSED\n");
					printf("---------------------------------\n");
				} break;
				case LISTENING: {
					printf("State: LISTENING\n");
					printf("---------------------------------\n");
					if(seg->header.type == SYN) { 
						recv_tcb->client_portNum = seg->header.src_port;
						recv_tcb->expect_seqNum = seg->header.seq_num;
						sendAck(seg, seg_ack, recv_tcb, SYNACK);
						recv_tcb->state = CONNECTED;
					}
				} break;
				case CONNECTED: {
					//printf("State: CONNECTED\n");
					//printf("---------------------------------\n");
					if(seg->header.type == SYN) {
						printf("State: CONNECTED -> SYN\n");
						recv_tcb->client_portNum = seg->header.src_port;
						recv_tcb->expect_seqNum = seg->header.seq_num;
						sendAck(seg, seg_ack, recv_tcb, SYNACK);
						recv_tcb->state = CONNECTED;
					}
					else if(seg->header.type == FIN ) {
						printf("State: CONNECTED -> FIN\n");
						if(recv_tcb->expect_seqNum == seg->header.seq_num) {
							sendAck(seg, seg_ack, recv_tcb, FINACK);
							recv_tcb->state = CLOSEWAIT;
						}
						else {
							printf("FIN Seq error!\n");
						}
					}
					else if(seg->header.type == DATA) {
						printf("State: CONNECTED -> DATA\n");
						//judge seq num
						printf("from port: %d to port %d, seq = %d, expected: %d\n", seg->header.src_port, seg->header.dest_port, seg->header.seq_num, recv_tcb->expect_seqNum);
						if(recv_tcb->expect_seqNum == seg->header.seq_num) {
							pthread_mutex_lock(recv_tcb->bufMutex);
							printf("data length: %d\n", seg->header.length);
							memcpy(recv_tcb->recvBuf+recv_tcb->usedBufLen, seg->data, seg->header.length);
							/*
							int i= 0;
							printf("\nin data recv-----------\n");
							for(i = 0; i<seg->header.length; i++) {
								printf("%c", (char *)(recv_tcb->recvBuf)[i]);
							}
							printf("\n-----------\n");
							*/
							/*
							printf("\n-------------\n usedbuflen: %d\n---------------\n",recv_tcb->usedBufLen);
							* */
							recv_tcb->usedBufLen += seg->header.length;
							/*
							printf("\n-------------\n usedbuflen: %d\n----------------\n",recv_tcb->usedBufLen);
							* */
							recv_tcb->expect_seqNum += seg->header.length;
							//recv_tcb->expect_seqNum %= MAX_SEG_LEN;
							//printf("\n+++++++++---------\nrecv_tcb->expect_seqNum = %d\n\n", recv_tcb->expect_seqNum);
							pthread_mutex_unlock(recv_tcb->bufMutex);
							sendAck(seg, seg_ack, recv_tcb, DATAACK);
						}
						else {
							printf("DATA Seq error!\n");
							seg_ack->header.type = DATAACK;
							seg_ack->header.src_port = seg->header.dest_port;
							seg_ack->header.dest_port = seg->header.src_port;
							seg_ack->header.seq_num = 0;
							seg_ack->header.ack_num = recv_tcb->expect_seqNum;
							seg_ack->header.length = 0;
							seg_ack->header.rcv_win=0;
							seg_ack->header.checksum = 0;
							seg_ack->header.checksum = checksum(seg_ack);
							sip_sendseg(global_conn, seg_ack);
						}
					}
				} break;
				case CLOSEWAIT: {
					printf("State: CLOSEWAIT\n");
					printf("---------------------------------\n");
					if(seg->header.type == FIN) {
						sendAck(seg, seg_ack, recv_tcb, FINACK);
						recv_tcb->state = CLOSEWAIT;
					}
				} break;
				default: break;
			}
		}
		else if(n == 1) {
			continue;
		}
	}
	return 0;
}
Пример #5
0
// 这是由stcp_client_init()启动的线程. 它处理所有来自服务器的进入段. 
// seghandler被设计为一个调用sip_recvseg()的无穷循环. 如果sip_recvseg()失败, 则说明重叠网络连接已关闭,
// 线程将终止. 根据STCP段到达时连接所处的状态, 可以采取不同的动作. 请查看客户端FSM以了解更多细节.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
void *seghandler(void* arg)
{
	seg_t recvbuf;
	int i = 0, n;
	while(1){
		if( (n = sip_recvseg(sipfd, &recvbuf)) == 0){
			for(i = 0; i <MAX_TRANSPORT_CONNECTIONS ; i++){
				if(tcb[i] != NULL && tcb[i]->client_portNum == recvbuf.header.dest_port
						&& tcb[i]->server_portNum == recvbuf.header.src_port){
					if(tcb[i]->state == SYNSENT && recvbuf.header.type == SYNACK){
						printf("client port %d receive SYNACK\n",
								tcb[i]->client_portNum);
						tcb[i]->state = CONNECTED;
					}
					//only recv DATAACK when connected
					if(tcb[i]->state == CONNECTED && recvbuf.header.type == DATAACK){
						int ack = recvbuf.header.ack_num;
						printf("client port %d receive DATAACK %d\n",
								tcb[i]->client_portNum, ack);
						pthread_mutex_lock(tcb[i]->bufMutex);
						assert(tcb[i]->sendBufHead != NULL);
						int num = tcb[i]->sendBufHead->seg.header.seq_num;
						printf("unAck_segNum %d \n", tcb[i]->unAck_segNum);
						while(num < ack){
							segBuf_t *tmp = tcb[i]->sendBufHead;
							tcb[i]->sendBufHead = tmp->next;
							printf("delete seg %d \n", tmp->seg.header.seq_num);
							free(tmp);
							tcb[i]->unAck_segNum--;
							printf("unAck_segNum -- %d\n", tcb[i]->unAck_segNum);
							if(tcb[i]->sendBufHead != NULL)
								num = tcb[i]->sendBufHead->seg.header.seq_num;
							else
								break;
						}
						while(tcb[i]->unAck_segNum < GBN_WINDOW && tcb[i]->sendBufunSent != NULL){
							tcb[i]->sendBufunSent->sentTime = time(NULL);
							printf("client send DATA %d \n", tcb[i]->sendBufunSent->seg.header.seq_num);
							sip_sendseg(sipfd, &(tcb[i]->sendBufunSent->seg));
							tcb[i]->sendBufunSent = tcb[i]->sendBufunSent->next;
							tcb[i]->unAck_segNum++;
							printf("unAck_segNum ++ %d\n", tcb[i]->unAck_segNum);
						}
						pthread_mutex_unlock(tcb[i]->bufMutex);
					}

					if(tcb[i]->state == FINWAIT && recvbuf.header.type == FINACK){
						printf("---------client port %d receive FINACK-----------\n",
								tcb[i]->client_portNum);
						tcb[i]->state = CLOSED;
					}
					break;
				}
			}
		}
		else if(n == -1){
//			printf("SON is closed\n");
			pthread_exit(NULL);
		}
	}
	pthread_exit(NULL);
}
Пример #6
0
// 这是由stcp_server_init()启动的线程. 它处理所有来自客户端的进入数据. seghandler被设计为一个调用sip_recvseg()的无穷循环, 
// 如果sip_recvseg()失败, 则说明到SIP进程的连接已关闭, 线程将终止. 根据STCP段到达时连接所处的状态, 可以采取不同的动作.
// 请查看服务端FSM以了解更多细节.
void* seghandler(void* arg) 
{
	long i;
	int flag;
	unsigned int client_port;
	seg_t* seg = (seg_t*)malloc(sizeof(seg_t));
	int* src_nodeID = (int*)malloc(sizeof(int));
	while (1) {
		flag = sip_recvseg(sip_conn, src_nodeID, seg);///////////////////////////////////注意src_nodeID的使用
		if (flag == 1) {//报文丢失
			printf("the stcp server does'n receive a segment! segment is lost!\n");
			continue;
		}
		if (checkchecksum(seg) == -1) {
			printf("Checksum error!\n");
			continue;
		}
		if (flag == -1) {//接收不到报文,线程停止
			printf("can't receive anything in tcp level, the seghandler thread is going to end.\n");
			break;
		}
		for (i = 0; i < MAX_TRANSPORT_CONNECTIONS; i++) {
			if ((NULL != server_tcb[i]) && (server_tcb[i]->server_portNum == seg->header.dest_port) && (server_tcb[i]->client_portNum == seg->header.src_port) && (*src_nodeID == server_tcb[i]->client_nodeID)) {
				break;
			}
		}
		if (i == MAX_TRANSPORT_CONNECTIONS) {
			printf("the tcb you want to find does't exist! but...\n");
			if (seg->header.type == SYN) {
				for (i = 0; i < MAX_TRANSPORT_CONNECTIONS; i++) {
					if ((NULL != server_tcb[i]) && (server_tcb[i]->server_portNum == seg->header.dest_port)) {
						break;
					}
				}
				if (i == MAX_TRANSPORT_CONNECTIONS) {
					printf("the tcb you want does't exist really!!\n");
					continue;
				}
			}
			else
				continue;
		}
		switch (seg->header.type) {
			case 0:
				printf("the type stcp server receives is SYN\n");
				break;
			case 1:
				printf("the type stcp server receives is SYNACK\n");
				break;
			case 2:
				printf("the type stcp server receives is FIN\n");
				break;
			case 3:
				printf("the type stcp server receives is FINACK\n");
				break;
			case 4:
				printf("the type stcp server receives is DATA\n");
				break;
			case 5:
				printf("the type stcp server receives is DATAACK\n");
				break;
		}
		client_port = seg->header.src_port;
		switch (server_tcb[i]->state) {
			case CLOSED:
				printf("stcp server now is in CLOSED state!\n");
				break;
			case LISTENING:
				printf("stcp server now is in LISTENING state!\n");
				if (seg->header.type == SYN) {
					printf("receive a SYN!\n");
					server_tcb[i]->state = CONNECTED;
					server_tcb[i]->client_portNum = seg->header.src_port;
					server_tcb[i]->client_nodeID = *src_nodeID;
					sendACK(i, client_port, *src_nodeID, SYNACK, seg);
				}
				break;
			case CONNECTED:
				printf("stcp server now is in CONNECTED state!\n");
				if (seg->header.type == SYN) {
					printf("receive a SYN!\n");
					server_tcb[i]->state = CONNECTED;
					server_tcb[i]->expect_seqNum = seg->header.seq_num;
					sendACK(i, client_port, *src_nodeID, SYNACK, seg);
				}
				else if (seg->header.type == FIN) {
					printf("receive a FIN!\n");
					server_tcb[i]->state = CLOSEWAIT;
					sendACK(i, client_port, *src_nodeID, FINACK, seg);
					pthread_t FINhandle_thread;
					int rc;
					rc = pthread_create(&FINhandle_thread, NULL, FINhandler, (void *)i);
					if (rc) {
						printf("ERROR; return code from pthread_create() is %d\n", rc);
						exit(-1);
					}
					
				}
				else if (seg->header.type == DATA) {
					printf("receive a DATA!\n");
					printf("the expect_seqNum is %d\n", server_tcb[i]->expect_seqNum);
					printf("the seqNum is %d\n", seg->header.seq_num);
					if (seg->header.seq_num == server_tcb[i]->expect_seqNum) {
						printf("the expect_seqNum == seq_num!\n");
						pthread_mutex_lock(server_tcb[i]->bufMutex);
						memcpy(server_tcb[i]->recvBuf + server_tcb[i]->usedBufLen, seg->data, seg->header.length);
						printf("the seg->header.length is %d\n", seg->header.length);
						server_tcb[i]->usedBufLen += seg->header.length;
						server_tcb[i]->expect_seqNum += seg->header.length;
						seg->header.src_port = server_tcb[i]->server_portNum;        //源端口号
						seg->header.dest_port = client_port;       //目的端口号
						seg->header.seq_num = 0;         //序号
						seg->header.ack_num = server_tcb[i]->expect_seqNum;         //确认号
						seg->header.length = 0;    //段数据长度
						seg->header.type = DATAACK;     //段类型
						seg->header.rcv_win = 0;  //当前未使用
						seg->header.checksum = 0;
						seg->header.checksum = checksum(seg);  //这个段的校验和
						sip_sendseg(sip_conn, *src_nodeID, seg);
						printf("stcp server send the changing DATAACK %d succesfully!\n", seg->header.ack_num);
						pthread_mutex_unlock(server_tcb[i]->bufMutex);
					}
					else {
						printf("the expect_seqNum != seq_num!\n");
						seg->header.src_port = server_tcb[i]->server_portNum;        //源端口号
						seg->header.dest_port = client_port;       //目的端口号
						seg->header.seq_num = 0;         //序号
						seg->header.ack_num = server_tcb[i]->expect_seqNum;         //确认号
						seg->header.length = 0;    //段数据长度
						seg->header.type = DATAACK;     //段类型
						seg->header.rcv_win = 0;  //当前未使用
						seg->header.checksum = 0;
						seg->header.checksum = checksum(seg);  //这个段的校验和
						sip_sendseg(sip_conn, *src_nodeID, seg);
						printf("stcp server send the not changed DATAACK %d succesfully!\n", seg->header.ack_num);
					}
				}
				break;
			case CLOSEWAIT:
				printf("stcp server now is in CLOSEWAIT state!\n");
				if (seg->header.type == FIN) {
					printf("receive a FIN!\n");
					sendACK(i, client_port, *src_nodeID, FINACK, seg);
				}
				break;
		}
	}
  	return 0;
}
Пример #7
0
void *seghandler(void* arg) {
	seg_t tmp;
	int src_node;
	while (1){
		int k = sip_recvseg(sip_connfd, &src_node, &tmp);
		print_pos();
		printf("sip_recvseg = %d\n", k);
		if( k == -1) {
//			usleep(100000);
			printf("\t\t\tWARNING: I lost a package\n");
		}
		else if (k == 2){
			sleep(1);
//			printf("unknown error\n");
		}
		else {
			switch(tmp.header.type){
				case SYN: printf("\t\t\t\tRECV SYN, client:%d server:%d\n", tmp.header.src_port, tmp.header.dest_port); break;
				case FIN: printf("\t\t\t\tRECV FIN, client:%d server:%d\n", tmp.header.src_port, tmp.header.dest_port); break;
				case DATA: printf("\t\t\t\tRECV DATA, client:%d server:%d\n", tmp.header.src_port, tmp.header.dest_port); break;
				default: break;
			}

			int i = 0, k = -1;
			for (i = 0; i < MAX_TRANSPORT_CONNECTIONS; i++) {
				if (tcb[i] != NULL) {
					if (tcb[i]->server_portNum == tmp.header.dest_port) {
						// 3种正常情况
						if (tmp.header.type == SYN && tcb[i]->state == LISTENING){
							printf("\tGOOD MSG: package right case 1: recv SYN\n");
							k = i;
							break;
						}
						if (tmp.header.type == DATA && tcb[i]->state == CONNECTED && tmp.header.src_port == tcb[i]->client_portNum){
							printf("\tGOOD MSG: package right case 2: recv DATA\n");
							k = i;
							break;
						}
						if (tmp.header.type == FIN && tcb[i]->state == CONNECTED && tmp.header.src_port == tcb[i]->client_portNum){
							printf("\tGOOD MSG: package right case 3: recv FIN\n");
							k = i;
							break;
						}
						// 错误情况2种
						if (tmp.header.type == SYN && tcb[i]->state == CONNECTED && tcb[i]->client_portNum == tmp.header.src_port){
							printf("PACKAGE ERROR: error case 1: recv SYN when CONNECTED\n");
							printf("\tERROR MSG: socket:%d client:%d server:%d\n", i, tcb[i]->client_portNum, tcb[i]->server_portNum);
							k = i;
							break;
						}
						if (tmp.header.type == FIN && tcb[i]->state == CLOSEWAIT && tcb[i]->client_portNum == tmp.header.src_port){
							printf("PACKAGE ERROR: error case 2: recv FIN when CLOSEWAIT\n");
							printf("\tERROR MSG: socket:%d client:%d server:%d\n", i, tcb[i]->client_portNum, tcb[i]->server_portNum);
							k = i;
							break;
						}
					}
				}
				else continue;
			}
			if (k == -1) {
				printf("PACKAGE ERROR: no such connect 4 package\n");
				printf("\tERROR MSG: package client:%d server:%d\n", tmp.header.src_port, tmp.header.dest_port);
			}
			else {
				switch(tcb[k]->state){
					case CLOSED: break;
					case LISTENING: 
						     if (tmp.header.type == SYN) {
							     tcb[k]->state = CONNECTED;
							     tcb[k]->client_portNum = tmp.header.src_port;

							     seg_t ack;
							     ack.header.src_port = tmp.header.dest_port;
							     ack.header.dest_port = tmp.header.src_port;
							     ack.header.seq_num = tcb[k]->expect_seqNum;
							     ack.header.ack_num = tmp.header.ack_num;
							     ack.header.length = 0;
							     ack.header.type = SYNACK;
							     ack.header.rcv_win = 0;
							     ack.header.checksum = 0;
							     memset(ack.data, 0, MAX_SEG_LEN);
							     ack.header.checksum = checksum(&ack);

							     printf("\tGOOD MSG: send SYNACK port:%d -> port:%d, src_node=%d\n", ack.header.dest_port, ack.header.src_port, src_node);
							     if (sip_sendseg(sip_connfd, src_node, &ack)) printf("\tGOOD MSG: send SYNACK ok\n");
							     else printf("SEND ERROR: send SYNACK failed\n");
						     }
						     break;
					case CONNECTED:
						     if (tmp.header.type == FIN){
							     tcb[k]->state = CLOSEWAIT;
							     tcb[k]->wait_start = clock();
							     seg_t ack;
							     ack.header.src_port = tmp.header.dest_port;
							     ack.header.dest_port = tmp.header.src_port;
							     ack.header.seq_num = tcb[k]->expect_seqNum;
							     ack.header.ack_num = tmp.header.ack_num;
							     ack.header.length = 0;
							     ack.header.type = FINACK;
							     ack.header.rcv_win = 0;
							     ack.header.checksum = 0;
							     memset(ack.data, 0, MAX_SEG_LEN);
							     ack.header.checksum = checksum(&ack);

							     printf("\tGOOD MSG: send SYNACK port:%d -> port:%d, src_node=%d\n", ack.header.dest_port, ack.header.src_port, src_node);
							     if (sip_sendseg(sip_connfd, src_node, &ack)) printf("\tGOOD MSG: send FINACK ok\n");
							     else printf("SEND ERROR: send FINACK failed\n");
						     }
						     else if (tmp.header.type == DATA){
							     int ackNum = -1;
							     if (tcb[k]->expect_seqNum == tmp.header.seq_num){	//是我想收的序号
								    if (tcb[k]->usedBufLen+tmp.header.length < RECEIVE_BUF_SIZE){//缓冲区未满
									    // printf("MSG: RECV data \'%s\'\n", tmp.data);
									     pthread_mutex_lock(tcb[k]->bufMutex);
									     memcpy(tcb[k]->recvBuf+tcb[k]->usedBufLen, tmp.data, tmp.header.length);
									     tcb[k]->expect_seqNum = tcb[k]->expect_seqNum+tmp.header.length;
									     tcb[k]->usedBufLen += tmp.header.length;
									     pthread_mutex_unlock(tcb[k]->bufMutex);

									     ackNum = tcb[k]->expect_seqNum;
								     }
							     }
							     seg_t ack;
							     ack.header.src_port = tmp.header.dest_port;
							     ack.header.dest_port = tmp.header.src_port;
							     ack.header.seq_num = tcb[k]->expect_seqNum;
							     ack.header.ack_num = tmp.header.seq_num;

							     ack.header.length = 0;
							     ack.header.type = DATAACK;
							     ack.header.rcv_win = 0;
							     ack.header.checksum = 0;
							     memset(ack.data, 0, MAX_SEG_LEN);
							     ack.header.checksum = checksum(&ack);
							     printf("MSG: recv seq_num %d, send ack_num %d\n", tmp.header.seq_num, ack.header.ack_num);
							     printf("MSG: RECV data length %d\n", tmp.header.length);
							     if (ackNum == -1) printf("DATA ERROR: expect %d, but recv %d\n", tcb[k]->expect_seqNum, tmp.header.seq_num);
							     else printf("\tGOOD MSG: recv data right seq:%d\n", tmp.header.seq_num);
							     printf("\tGOOD MSG: send DATAACK 4 client:%d -> server:%d\n", ack.header.dest_port, ack.header.src_port);
							     if (sip_sendseg(sip_connfd, src_node, &ack)) printf("\tGOOD MSG: send DATAACK ok\n");
							     else printf("SEND ERROR: send DATAACK failed\n");

						     }
						     else if (tmp.header.type == SYN){
							     seg_t ack;
							     ack.header.src_port = tmp.header.dest_port;
							     ack.header.dest_port = tmp.header.src_port;
							     ack.header.seq_num = tcb[k]->expect_seqNum;
							     ack.header.ack_num = tmp.header.ack_num;
							     ack.header.length = 0;
							     ack.header.type = SYNACK;
							     ack.header.rcv_win = 0;
							     ack.header.checksum = 0;
							     memset(ack.data, 0, MAX_SEG_LEN);
							     ack.header.checksum = checksum(&ack);

							     printf("SEND ERROR: SYNACK lost\n"); 
							     printf("\tGOOD MSG: send SYNACK 4 client:%d -> server:%d\n", ack.header.dest_port, ack.header.src_port);
							     if (sip_sendseg(sip_connfd, src_node, &ack)) printf("\tGOOD MSG: send SYNACK ok\n");
							     else printf("SEND ERROR: send SYNACK failed\n");
						     }
						     break;
					case CLOSEWAIT: 
						     if (tmp.header.type == FIN){
							     tcb[k]->wait_start = clock();
							     seg_t ack;
							     ack.header.src_port = tmp.header.dest_port;
							     ack.header.dest_port = tmp.header.src_port;
							     ack.header.seq_num = tcb[k]->expect_seqNum;
							     ack.header.ack_num = tmp.header.ack_num;
							     ack.header.length = 0;
							     ack.header.type = FINACK;
							     ack.header.rcv_win = 0;
							     ack.header.checksum = 0;
							     memset(ack.data, 0, MAX_SEG_LEN);
							     ack.header.checksum = checksum(&ack);

							     printf("SEND ERROR: FINACK lost\n"); 
							     printf("\tGOOD MSG: send FINACK 4 client:%d -> server:%d\n", ack.header.dest_port, ack.header.src_port);
							     if (sip_sendseg(sip_connfd, src_node, &ack)) printf("\tGOOD MSG: send FINACK ok\n");
							     else printf("SEND ERROR: send FINACK failed\n");
						     }
						     break;
					default: break;
				}
			}
		}
	}
  return 0;
}
Пример #8
0
// 这是由stcp_client_init()启动的线程. 它处理所有来自服务器的进入段. 
// seghandler被设计为一个调用sip_recvseg()的无穷循环. 如果sip_recvseg()失败, 则说明到SIP进程的连接已关闭,
// 线程将终止. 根据STCP段到达时连接所处的状态, 可以采取不同的动作. 请查看客户端FSM以了解更多细节.
void* seghandler(void* arg) 
{
	int rslt;
	while(1)
	{
		int severNodeID;
		seg_t* seg=(seg_t *)malloc(sizeof(seg_t));
		memset(seg, 0, sizeof(seg_t));
		rslt=sip_recvseg(sip_conn, &severNodeID, seg);
		if(rslt < 0) {
			printf("Receive seg lost or error!\n");
			continue;
		}
		if(checkchecksum(seg)==-1) {
			printf("Receive seg Checksum error\n");
			continue;
		}
		if(rslt>0) {
			int i = 0;
			for(i=0;i<MAX_TRANSPORT_CONNECTIONS;i++)
			{
				if(client_tcb_table[i]!=NULL){
					if(client_tcb_table[i]->client_portNum == seg->header.dest_port){
						//printf("======= i = %d ========\n", i);
						break;
					}
				}
			}
			if(i == MAX_TRANSPORT_CONNECTIONS) {
				printf("TCB ERROR!\n");
				continue;
			}
			client_tcb_t* recv_tcb = client_tcb_table[i];
			switch(client_tcb_table[i]-> state)	{
				case CLOSED: {
					printf("State: CLOSED\n");
					//printf("---------------------------------\n");
				} break;
									
				case SYNSENT: {
					printf("State: SYNSENT\n");
					//printf("---------------------------------\n");
					if(seg->header.type==SYNACK){
						printf("recv SYNACK from server_port: %d\n", seg->header.src_port);
						client_tcb_table[i]->state=CONNECTED;
					}
				} break;
				case CONNECTED: 
					if(seg->header.type == DATAACK)
					{	
						printf("State: CONNECTED -> DATAACK\n");
						pthread_mutex_lock(client_tcb_table[i]->bufMutex);
						//segBuf_t *phead = recv_tcb->sendBufHead;
						int ack = seg->header.ack_num;
						printf("ACK: %d\n", ack);
						// <=ack 的都被确认为收到,不需要再发送
						if(recv_tcb->sendBufHead!= NULL) {
							int n = ack - recv_tcb->sendBufHead->seg.header.seq_num;
							while(n > 0) {
								segBuf_t *phead = recv_tcb->sendBufHead;
								recv_tcb->sendBufHead = phead->next;
								n -= phead->seg.header.length;
								free(phead);
								recv_tcb->unAck_segNum--;
								if(recv_tcb->sendBufunSent != NULL) {
									printf("send data to server, seq: %d\n", recv_tcb->sendBufunSent->seg.header.seq_num);
									sip_sendseg(sip_conn, recv_tcb->server_nodeID, &(recv_tcb->sendBufunSent->seg));
									struct timeval sentTime;
									gettimeofday(&sentTime, 0);
									recv_tcb->sendBufunSent->sentTime_usec = sentTime.tv_usec;
									client_tcb_table[i]->sendBufunSent->sentTime_sec = sentTime.tv_sec;
									recv_tcb->sendBufunSent= recv_tcb->sendBufunSent->next;
									recv_tcb->unAck_segNum++;
								}
							}
						}
						pthread_mutex_unlock(client_tcb_table[i]->bufMutex);
					}
                break;
					
				case FINWAIT: {
					if(seg->header.type == FINACK)
					{
						printf("recv FINACK from server_port: %d\n", seg->header.src_port);
						client_tcb_table[i]->state = CLOSED;
					}
				} break;
            	default: break;
			}
		}
		free(seg);
   }
   return 0;
}
Пример #9
0
void *seghandler(void* arg) {

	seg_t seg_data;
	segBuf_t* p;
	int i;
	int ack_num;
	int nodeID;
	while(sip_recvseg(sip_conn,&nodeID,&seg_data)!=-1){
		i=0;
		unsigned int temp;
		while(tcbtable[i]!=NULL && tcbtable[i]->server_portNum!=seg_data.header.src_port && i<MAX_TRANSPORT_CONNECTIONS)i++;
		if(i >= MAX_TRANSPORT_CONNECTIONS)  return;
		switch(seg_data.header.type){
		case SYNACK:
			if(tcbtable[i]->state == SYNSENT) tcbtable[i]->state=CONNECTED;
			break;
		case FINACK:
			if(tcbtable[i]->state == FINWAIT) tcbtable[i]->state=CLOSED;
			break;
		case DATAACK:
			if(tcbtable[i]->state == CONNECTED){
				p = tcbtable[i]->sendBufHead;
				ack_num = seg_data.header.ack_num;
				//释放空间
				pthread_mutex_lock(tcbtable[i]->send_bufMutex);
				while(tcbtable[i]->unAck_segNum > 0 && p != NULL && p->seg.header.seq_num < ack_num ){
					tcbtable[i]->sendBufHead = tcbtable[i]->sendBufHead->next;
					free(p);
					p = tcbtable[i]->sendBufHead;
					tcbtable[i]->unAck_segNum--;
				}
				pthread_mutex_unlock(tcbtable[i]->send_bufMutex);
			}
			break;
		case DATA:
			if(tcbtable[i]->state==CONNECTED)
			{
				if(seg_data.header.seq_num==tcbtable[i]->expect_seqNum)
				{
					int len=seg_data.header.length-sizeof(stcp_hdr_t);
					pthread_mutex_lock(tcbtable[i]->rec_bufMutex);
					memcpy((char *)tcbtable[i]->recvBuf+tcbtable[i]->usedBufLen,(char *)&seg_data.data,len);
					tcbtable[i]->usedBufLen+=len;
					tcbtable[i]->expect_seqNum+=len;
					pthread_mutex_unlock(tcbtable[i]->rec_bufMutex);		
				}
				temp=seg_data.header.src_port;
				seg_data.header.src_port=seg_data.header.dest_port;
				seg_data.header.dest_port=temp;
				seg_data.header.type = DATAACK;
				seg_data.header.ack_num = tcbtable[i]->expect_seqNum;	
				seg_data.header.checksum=0;
				seg_data.header.length=sizeof(stcp_hdr_t);
				seg_data.header.checksum=checksum(&seg_data);
				sip_sendseg(sip_conn,tcbtable[i]->server_nodeID,&seg_data);	
			} 
			 break;
		default:
			printf("server wrong\n");break;
	}
	}
  return 0;
}
Пример #10
0
// 这是由stcp_client_init()启动的线程. 它处理所有来自服务器的进入段. 
// seghandler被设计为一个调用sip_recvseg()的无穷循环. 如果sip_recvseg()失败, 则说明到SIP进程的连接已关闭,
// 线程将终止. 根据STCP段到达时连接所处的状态, 可以采取不同的动作. 请查看客户端FSM以了解更多细节.
void* seghandler(void* arg) 
{

	pthread_detach(pthread_self());	//modify

  	seg_t recv_segment;
	int sockfd;
	int connection_state;
	int src_nodeID;
	while (true) {
		connection_state = sip_recvseg(sip_conn, &src_nodeID, &recv_segment);
		
		//the segment is lost
		if (connection_state == -1) {
			continue;
		}
		
		sockfd = stcp_get_sockfd(&recv_segment);
		client_tcb_t *tcb = client_tcb_table[sockfd];
		
		assert(src_nodeID == tcb -> server_nodeID);

		//sockfd error
		if (sockfd == -1) {
			continue;
		}
		
		//SYNACK
		if (recv_segment.header.type == SYNACK) {
			if (tcb -> state == SYNSENT) {
				tcb -> state = CONNECTED;
			}
		}
		
		//FINACK
		if (recv_segment.header.type == FINACK) {
			if (tcb -> state == FINWAIT) {
				tcb -> state = CLOSED;
			}
		}

		//DATAACK
		if (recv_segment.header.type == DATAACK) {
			if(tcb -> state == CONNECTED){
				
				//printf("receive a dataack segment, ack %d\n", recv_segment.header.ack_num);

				int ack = recv_segment.header.ack_num;

				pthread_mutex_lock(tcb -> bufMutex);

				segBuf_t* bufhead = tcb -> sendBufHead;

				//ack segs those seq<ack
				while(bufhead -> seg.header.seq_num < ack){
					
					tcb -> sendBufHead = tcb -> sendBufHead -> next;
					
				//	printf("free segment in buf, seq %d\n", bufhead -> seg.header.seq_num);
					free(bufhead);

					bufhead = tcb -> sendBufHead;
					tcb -> unAck_segNum --;
					
					if(bufhead == NULL){
						assert(tcb -> sendBufunSent == NULL);
						tcb -> sendBufTail = NULL;
						break;
					}
				}

				//send blocked segments(if exist)
				while(tcb -> sendBufunSent != NULL && tcb -> unAck_segNum < GBN_WINDOW){
				
					sip_sendseg(sip_conn, tcb -> server_nodeID, &(tcb -> sendBufunSent -> seg));
					printf("send a data segment, seq %d\n", (tcb -> sendBufunSent -> seg). header.seq_num);

					tcb -> sendBufunSent -> sentTime = get_time();
					tcb -> unAck_segNum ++;
					tcb -> sendBufunSent = tcb -> sendBufunSent -> next;
				}
				pthread_mutex_unlock(tcb -> bufMutex);
			}
		}
	}
}
Пример #11
0
// 这是由stcp_client_init()启动的线程. 它处理所有来自服务器的进入段. 
// seghandler被设计为一个调用sip_recvseg()的无穷循环. 如果sip_recvseg()失败, 则说明重叠网络连接已关闭,
// 线程将终止. 根据STCP段到达时连接所处的状态, 可以采取不同的动作. 请查看客户端FSM以了解更多细节.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
void *seghandler(void* arg)
{
	int i;
	int flag;
	while (1) {
		seg_t* seg = (seg_t*)malloc(sizeof(seg_t));
		flag = sip_recvseg(gSockFd, seg);
		if (flag == 1) {//报文丢失
			printf("the stcp client does'n receive a segment! segment is lost!\n");
			continue;
		}
		if (flag == -1) {//接收不到报文,线程停止
			printf("can't receive anything in tcp level, the seghandler thread is going to end.\n");
			break;
		}
		if (checkchecksum(seg) == -1) {
			printf("Checksum error!\n");
			continue;
		}
		for (i = 0; i < client_tcb_size; i++) {
			if (NULL != client_tcb[i] && (client_tcb[i]->server_portNum == seg->header.src_port && client_tcb[i]->client_portNum == seg->header.dest_port)) {
				break;
			}
		}
		if (i == client_tcb_size) {
			printf("the tcb you want to find does't exist!\n");
			continue;
		}
		printf("the type stcp client receives is %d\n", seg->header.type);
		switch (client_tcb[i]->state) {
			case CLOSED:
				printf("stcp client now is in CLOSED state!\n");
				if (seg->header.type == SYN) {
					client_tcb[i]->state = SYNSENT;
				}
				break;
			case SYNSENT:
				printf("stcp client now is in SYNSENT state!\n");
				if (seg->header.type == SYNACK) {
					printf("receive a SYNACK!\n");
					client_tcb[i]->state = CONNECTED;
				}
				break;
			case CONNECTED:
				printf("stcp client now is in CONNECTED state!\n");
				if (seg->header.type == DATAACK) {
					printf("receive a DATAACK %d!\n", seg->header.ack_num);
					pthread_mutex_lock(client_tcb[i]->bufMutex);
					segBuf_t *p = client_tcb[i]->sendBufHead;
					while (p != NULL && p != client_tcb[i]->sendBufunSent) {
					    if (p->seg.header.seq_num < seg->header.ack_num) {
						   	client_tcb[i]->sendBufHead = p->next;
							printf("delete the %d seq_no\n", p->seg.header.seq_num);
							free(p);
							p = client_tcb[i]->sendBufHead;
							client_tcb[i]->unAck_segNum--;
					    }
						else break;/////////////////////////////////
					}
					//不该重发
					/*p = client_tcb[i]->sendBufHead;
					while (p != NULL && p != client_tcb[i]->sendBufunSent) {//重发,unAck_segNum不用加一
						p->sentTime = getCurrentTime();
						sip_sendseg(gSockFd, &(p->seg));
						p = p->next;
					}*/
					while((client_tcb[i]->unAck_segNum < GBN_WINDOW) && (client_tcb[i]->sendBufunSent != NULL)) {
						client_tcb[i]->sendBufunSent->sentTime = getCurrentTime();
						sip_sendseg(gSockFd, &(client_tcb[i]->sendBufunSent->seg));
						client_tcb[i]->sendBufunSent = client_tcb[i]->sendBufunSent->next;
						client_tcb[i]->unAck_segNum++;
					}
					pthread_mutex_unlock(client_tcb[i]->bufMutex);
				}
				break;
			case FINWAIT:
				printf("stcp client now is in FINWAIT state!\n");
				if (seg->header.type == FINACK) {
					printf("receive a FINACK!\n");
					client_tcb[i]->state = CLOSED;
				}
				break;
		}
	}
  	return 0;
}
Пример #12
0
void *seghandler(void* arg) {
	seg_t *segPtr = (seg_t*)malloc(sizeof(seg_t));
	while (1) {
		int count = sip_recvseg(connection, segPtr);
		if ( count > 0) {
			unsigned short int type = segPtr->header.type;
			// 查找该数据段的TCB
			unsigned int client_port = segPtr->header.dest_port;
			int sockfd;
			for (sockfd = 0; sockfd < MAX_TRANSPORT_CONNECTIONS; sockfd ++) {
				if (tcb_table[sockfd] != NULL) {
					if (tcb_table[sockfd]->client_portNum == client_port) {
						break;
					}
				}
			}
			// client FSM
			switch(tcb_table[sockfd]->state) {
				case SYNSENT:
				if (type == SYNACK) {
					tcb_table[sockfd]->state = CONNECTED;
					printf("Client(SYNSENT): Get a SYNACK, state changes: SYNSENT---->CONNECTED\n");
				}
				break;
				case CONNECTED:
					if (type == DATAACK) {
						int ack_num = segPtr->header.ack_num;	// !!!!!!!!!!!!!!!
						printf("Client: Get a DATAACK from Server(expect_num is %d)\n", ack_num);
						pthread_mutex_lock(tcb_table[sockfd]->bufMutex);
						segBuf_t *q = tcb_table[sockfd]->sendBufHead;
						segBuf_t *p = NULL;
						while (q != tcb_table[sockfd]->sendBufunSent) { //释放发送缓冲区
							if (q->seg.header.seq_num < ack_num) {	
								p = q;
								q = q->next;
								free(p);
							}
							else 
								break;
						}
						tcb_table[sockfd]->sendBufHead = q;
						//  发送数据段直到已发送但未被确认的段数量到达GBN_WINDOW为止 
						int ack_sum = 0;
						segBuf_t *q1 = tcb_table[sockfd]->sendBufHead;
						for (;q1 != tcb_table[sockfd]->sendBufunSent && q1 != NULL; q1 = q1->next)
							ack_sum ++;
	
						while (ack_sum < GBN_WINDOW) {
							if (tcb_table[sockfd]->sendBufunSent == NULL) break;
							printf("Client:send data to server(seq_num is %d)\n", tcb_table[sockfd]->sendBufunSent->seg.header.seq_num);
							sip_sendseg(connection, &tcb_table[sockfd]->sendBufunSent->seg);
							ack_sum ++;
							tcb_table[sockfd]->sendBufunSent = tcb_table[sockfd]->sendBufunSent->next;
						}
						//printf("ack_sum is %d-----------------------------\n", ack_sum);
						pthread_mutex_unlock(tcb_table[sockfd]->bufMutex);
					}
				break;
				case FINWAIT:
				if (type == FINACK) {
					tcb_table[sockfd]->state = CLOSED;
					printf("Client(FINWAIT): GET a FINACK, state changes: FINWAIT----->CLOSED\n");
				}
				break;
				
			}
		}
		else if (count == 0);	// 段数据丢失
		else		// TCP 连接断开
			break;
	}
	free(segPtr);
	segPtr = NULL;
	pthread_exit(0);
}