コード例 #1
0
void gui()
{
	printf("/********************---Welcome---**********************\\\n");
	printf("/***                电子地图信息统计系统             ***\\\n");
	printf("/***                第12组    2015年9月              ***\\\n");
	printf("/*******************************************************\\\n");

	Road* roads = NULL;

	while (true)
	{
		printTips();

		int choose;
		scanf("%d", &choose);
		switch (choose)
		{
			case 1:
			{
				readFile(&roads);
				break;
			}

			case 2:
			{
				sortRecords(roads);
				break;
			}

			case 3:
			{
				searchRecords(roads);
				break;
			}

			case 4:
			{
				updateData(roads);
				break;
			}

			case 0:
			{
				printf("谢谢您的使用!\n");
				return;
			}


			default:
			{
				printf("无法识别的操作,程序即将退出。\n");
				Sleep(2500);
				return;
			}
		}
	}

}
コード例 #2
0
int main(int argc, char* argv[])
{
	//加载套接字库(必须) 
	WORD wVersionRequested;
	WSADATA wsaData;
	//套接字加载时错误提示 
	int err;
	//版本 2.2 
	wVersionRequested = MAKEWORD(2, 2);
	//加载 dll 文件 Scoket 库   
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0){
		//找不到 winsock.dll 
		printf("WSAStartup failed with error: %d\n", err);
		return 1;
	}
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		printf("Could not find a usable version of Winsock.dll\n");
		WSACleanup();
	}
	else{
		printf("The Winsock 2.2 dll was found okay\n");
	}
	SOCKET socketClient = socket(AF_INET, SOCK_DGRAM, 0);
	SOCKADDR_IN addrServer;
	addrServer.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(SERVER_PORT);
	//接收缓冲区 
	char buffer[BUFFER_LENGTH];
	ZeroMemory(buffer, sizeof(buffer));
	int len = sizeof(SOCKADDR);
	//为了测试与服务器的连接,可以使用  -time  命令从服务器端获得当前时间
	//使用  -testgbn [X] [Y]  测试 GBN  其中[X]表示数据包丢失概率 
	//                    [Y]表示 ACK 丢包概率 
	printTips();
	int ret;
	int interval = 1;//收到数据包之后返回 ack 的间隔,默认为 1 表示每个都返回 ack,0 或者负数均表示所有的都不返回 ack
	char cmd[128];
	float packetLossRatio = 0.2;  //默认包丢失率 0.2 
	float ackLossRatio = 0.2;  //默认 ACK 丢失率 0.2 
	//用时间作为随机种子,放在循环的最外面 
	srand((unsigned)time(NULL));
	while (true){
		gets_s(buffer);
		ret = sscanf(buffer, "%s%f%f", &cmd, &packetLossRatio, &ackLossRatio);
		//开始 GBN 测试,使用 GBN 协议实现 UDP 可靠文件传输 
		if (!strcmp(cmd, "-testgbn")){
			printf("%s\n", "Begin to test GBN protocol, please don't abort the process");
			printf("The  loss  ratio  of  packet  is  %.2f,the  loss  ratio  of  ack is %.2f\n", packetLossRatio, ackLossRatio);
			int waitCount = 0;
			int stage = 0;
			BOOL b;
			unsigned char u_code;//状态码 
			unsigned short seq;//包的序列号 
			unsigned short recvSeq;//已确认的最大序列号 
			unsigned short waitSeq;//等待的序列号 ,窗口大小为10,这个为最小的值
			char buffer_1[RECV_WIND_SIZE][BUFFER_LENGTH];//接收到的缓冲区数据----------------add bylvxiya
			int i_state = 0;
			for (i_state = 0; i_state < RECV_WIND_SIZE; i_state++){
				ZeroMemory(buffer_1[i_state],sizeof(buffer_1[i_state]));
			}

			BOOL ack_send[RECV_WIND_SIZE];//ack发送情况的记录,对应1-20的ack,刚开始全为false
			int success_number=0;// 窗口内成功接收的个数
			for (i_state = 0; i_state < RECV_WIND_SIZE; i_state++){//记录哪一个成功接收了
				ack_send[i_state] = false;
			}
			std::ofstream out_result;
			out_result.open("result.txt", std::ios::out | std::ios:: trunc);
			if (!out_result.is_open()){
				printf("文件打开失败!!!\n");
				continue;
			}
			//---------------------------------
			sendto(socketClient, "-testgbn", strlen("-testgbn") + 1, 0,
				(SOCKADDR*)&addrServer, sizeof(SOCKADDR));
			while (true)
			{
				//等待 server 回复设置 UDP 为阻塞模式 
				recvfrom(socketClient, buffer, BUFFER_LENGTH, 0, (SOCKADDR*)&addrServer, &len);
				switch (stage){
				case 0://等待握手阶段 
					u_code = (unsigned char)buffer[0];
					if ((unsigned char)buffer[0] == 205)
					{
						printf("Ready for file transmission\n");
						buffer[0] = 200;
						buffer[1] = '\0';
						sendto(socketClient, buffer, 2, 0,
							(SOCKADDR*)&addrServer, sizeof(SOCKADDR));
						stage = 1;
						recvSeq = 0;
						waitSeq = 1;
					}
					break;
				case 1://等待接收数据阶段 
					if (!memcmp(buffer, "good bye\0", 9)){
						printf("数据传输成功!!!\n");
						goto success;
					}
					seq = (unsigned short)buffer[0];
					//随机法模拟包是否丢失 
					b = lossInLossRatio(packetLossRatio);
					if (b){
						printf("The packet with a seq of %d loss\n", seq);
						continue;
					}
					printf("recv a packet with a seq of %d\n", seq);
					//如果是期待的包的范围,正确接收,正常确认即可,如果小于期待的范围,直接回应ack 
					if ((seq<waitSeq && (waitSeq + RECV_WIND_SIZE>SEQ_SIZE ? seq >= (waitSeq + RECV_WIND_SIZE) % SEQ_SIZE :true)))//在接收窗口范围内
					{
						buffer[0] = seq;
						buffer[1] = '\0';
					}
					else if (seq >= waitSeq && (waitSeq + RECV_WIND_SIZE>SEQ_SIZE ? true: seq < (waitSeq + RECV_WIND_SIZE))){//在接收窗口范围内
						/*if (!(seq - waitSeq))
						{
							++waitSeq;
							if (waitSeq == 21){
								waitSeq = 1;
							}
							//在这里应该向上层交付数据
						}*/
						memcpy(buffer_1[seq - waitSeq], &buffer[1], sizeof(buffer));
						ack_send[seq - waitSeq] = true;
						int ack_s = 0;
						while (ack_send[ack_s] && ack_s<RECV_WIND_SIZE){
							//向上层传输数据							
							out_result << buffer_1[ack_s];
							//printf("%s",buffer_1[ack_s - 1]);
							ZeroMemory(buffer_1[ack_s], sizeof(buffer_1[ack_s]));
							waitSeq++;
							if (waitSeq == 21){
								waitSeq = 1;
							}
							ack_s = ack_s + 1;
						}
						if (ack_s > 0){
							for (int i = 0; i < RECV_WIND_SIZE; i++){
								if (ack_s + i < RECV_WIND_SIZE)
								{
									ack_send[i] = ack_send[i + ack_s];
									memcpy(buffer_1[i], buffer_1[i + ack_s], sizeof(buffer_1[i + ack_s]));
									ZeroMemory(buffer_1[i + ack_s], sizeof(buffer_1[i + ack_s]));
								}
								else
								{
									ack_send[i] = false;
									ZeroMemory(buffer_1[i], sizeof(buffer_1[i]));
								}
									
							}
						}
						
						//输出数据 
						//printf("%s\n",&buffer[1]); 
						buffer[0] = seq;
						recvSeq = seq;
						buffer[1] = '\0';
					}
					else{
						//如果当前一个包都没有收到,则等待 Seq 为 1 的数据包,不是则不返回 ACK(因为并没有上一个正确的 ACK)
						if (!recvSeq){
							continue;
						}
						buffer[0] = recvSeq;
						buffer[1] = '\0';
					}
					b = lossInLossRatio(ackLossRatio);
					if (b){
						printf("The  ack  of  %d  loss\n", (unsigned
							char)buffer[0]);
						continue;
					}
					sendto(socketClient, buffer, 2, 0,
						(SOCKADDR*)&addrServer, sizeof(SOCKADDR));
					printf("send a ack of %d\n", (unsigned char)buffer[0]);
					break;
				}
				Sleep(500);
			}
		success:			out_result.close();
		}
		sendto(socketClient, buffer, strlen(buffer) + 1, 0,
			(SOCKADDR*)&addrServer, sizeof(SOCKADDR));
		ret =
			recvfrom(socketClient, buffer, BUFFER_LENGTH, 0, (SOCKADDR*)&addrServer,
			&len);
		printf("%s\n", buffer);
		if (!strcmp(buffer, "Good bye!")){
			break;
		}
		printTips();
	}
	//关闭套接字 
	closesocket(socketClient);
	WSACleanup();
	return 0;
}