本文介绍了使用和弦协议,制作p2p网络节点(C)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有和弦协议模拟器代码

使用这个,我想制作p2p网络节点



I have chord protocol simulator code
using this, I want to make p2p network node

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <winsock2.h>
#include <string.h>

#define nodefmax 10              /* Max number of files in a node */
#define FNameMax 32             /* Max length of File Name */
#define FDataMax 64				/* Max length of File Data */

struct fileStru {				/* File Structure */
	char Name[FNameMax];		/* File Name */
	int  Key;					/* File Key */
	struct nodeInfo *owner;			/* file Owner */
	char *Data;                 /* File Data */
};

struct fileInfo {               /* Global Information of Current Files */
	int fileNum;				/* The Number of Current Files */
	struct fileStru file[nodefmax];	/* Information of Each File */
};

struct fingerTable {			/* Finger Table Structure */
	struct nodeInfo *Pre;		/* Predecessor pointer */
	struct nodeInfo **finger;	/* Fingers (array of pointers) */
};

struct chordInfo {              /* Chord Information Structure */
	struct fileInfo ownFRef;    /* File Ref Own Information */
	struct fingerTable fingerInfo;  /* Finger Table Information */
};

struct nodeData {
	int ID;						/* Node's ID */
	struct fileInfo ownFile;    /* File Own Information */
	struct chordInfo chordData; /* Chord Data Information */
};

struct nodeInfo {				/* Node Structure */
	struct in_addr ipaddr;      /* Node's IPv4 Address */
	struct nodeData Data;		/* Node's Data */
	struct nodeInfo *nextNode;  /* Next node pointer */
};



typedef struct nodeInfo nodeType;
typedef struct fileStru fileType;

int baseM;						/* Base size (m bit) of Chord Space */
int ringSize = 1;				/* Chord Space Size */

nodeType *netHead = NULL, *netTail = NULL;	/* Main pointer to networked nodes */

int fix_finger(nodeType *curNode);
// For Fix_Finger of a Node; May Return the result   

nodeType *find_successor(nodeType *curNode, int IDKey);
// For finding successor of IDKey for a node curNode

nodeType *find_predecessor(nodeType *curNode, int IDKey);
// For finding predecessor of IDKey for a node curNode

nodeType *find_closest_predecessor(nodeType *curNodeID, int IDKey);
// For finding closest predecessor of IDKey for a node curNode

int lookup(nodeType *curNode, int fileKey, nodeType **foundNode);
// For looking up a file with filekey at a node curNode
// Found node pointer is stored at *foundNode
// May return the result

void stabilize(nodeType *curNode);
// For stabilizing the Predecessor and the successor around Node

void notify(nodeType *askNode, nodeType *targetNode);
// For targetNode's asking askNode to change its predecessor  

int join(nodeType *joinNode, nodeType *helpNode);
// For Joining a joinNode with a help of helpNode
// May return the result

void initialize(nodeType *joinNode, nodeType *helpNode);
// For Initializing a join node, joinNode with a help of helpNode

int move_keys(nodeType *toNode, nodeType *fromNode);
// For moving file keys from Node with fromNodeID to Node with toNodeID
// when joining or leaving a node
// May return the result

unsigned int str_hash(const char *);
// A Hash Function from a string to the ID/key space

int twoPow(int power);
// For getting a power of 2 

int modMinus(int modN, int minuend, int subtrand);
// For modN modular operation of "minend - subtrand"

int modPlus(int modN, int addend1, int addend2);
// For modN modular operation of "addend1 + addend2"

int modIn(int modN, int targNum, int range1, int range2, int leftmode, int rightmode);
// For checking if targNum is "in" the range using left and right modes 
// under modN modular environment 

void printNodes(void);  // Print current node information
void printFiles(void);  // Print current file information
int  countNodes(void);  // Count current nodes
int  countFiles(void);  // Count current files
nodeType *getNode(int number); // Get number-th node pointer
fileType getFile(int number);  // Get number-th file information

int main(void)
{
	/* step 1: Initial Setup for nodes and files - manual or random  */
	/* step 2: Construct CHORD Table and Distributing File Information */
	/* step 3: Commands:  */

	/* step 1 */

	int initNode;  // No of Initial Nodes
	int initFile;  // No of Initial Files
	int curID, tempID, Found = 0, tempNum = 0;
	struct in_addr curIP;
	char *curIPstr;
	char curName[FNameMax] = { 0 }, tempStr[FNameMax] = { 0 }, tempIPstr[16] = { 0 };
	int curKey, noFile = 0;
	int nodeNum = 0, randFName;
	int fileNum = 0, ownNodeNo;
	int i = 0, j = 0, k = 0;
	int sameExist = 0, result;
	unsigned char randIPsec[4];
	int USel = 0, USel2 = 0, USel3 = 0;
	nodeType *curNode, *tempNode, *targetNode, *foundNode;
	fileType targetFile, foundFile;

	srand(time(NULL));

	printf("*****************************************************************\n");
	printf("*      DHT-Based P2P Protocol (CHORD) Functional Simulator      *\n");
	printf("*                  Ver. 0.6      Aug. 30, 2016                   *\n");
	printf("*                       (c) Kim, Tae-Hyong                      *\n");
	printf("*****************************************************************\n\n");

	printf("Note: This CHORD simulator has 4 steps.\n");
	printf("-----------------------------------------------------------------\n");
	printf("STEP 1: Initialization of CHORD Networks\n");

	printf("   ** A. Network Space Initialization\n");

	printf("      => Input the base number (m>2) of Chord Space : ");//3이상의 Chord space 사이즈를 정한다
	do {
		fflush(stdin);
		scanf("%d", &baseM);
	} while (baseM < 3);

	for (i = 0; i<baseM; i++)
		ringSize *= 2;//동그라미 크기

	printf("   ** B. Node Initialization : Automatic Mode\n");

	printf("      => Input the number of initial nodes (<%d) : ", ringSize / 4);

	do {
		fflush(stdin);
		scanf("%d", &initNode);
	} while ((initNode < 1) || (initNode > ringSize / 4));//고른 노드 분포

	while (nodeNum < initNode) {

		sameExist = 0;

		for (i = 0; i<4; i++)            /* Random IP address generation */
			randIPsec[i] = rand() % 255 + 1;

		curIP.S_un.S_addr = randIPsec[3] * 256 * 256 * 256 + randIPsec[2] * 256 * 256 +
			randIPsec[1] * 256 + randIPsec[0];
		curIPstr = inet_ntoa(curIP);

		tempNode = netHead;

		while (tempNode != NULL) {   /* if not the first time */
			if (!memcmp(&curIP, &(tempNode->ipaddr), sizeof(struct in_addr))) {
				sameExist = 1; /* IP address Already Exists */
				break;         /* Choose Other */
			}
			tempNode = tempNode->nextNode;
		}

		if (!sameExist) {
			curID = str_hash(curIPstr);
			tempNode = netHead;
			while (tempNode != NULL) {   /* if not the first time */
				if (curID == tempNode->Data.ID) {
					sameExist = 1; /* ID Already Exists */
					break;         /* Choose Other */
				}
				tempNode = tempNode->nextNode;
			}
		}

		if (!sameExist) {
			tempNode = (nodeType *)calloc(1, sizeof(nodeType));

			if (netHead != NULL) {  /* not the first node */
				netTail->nextNode = tempNode;
				netTail = tempNode;
			}
			else {					/* the first node */
				netHead = tempNode;
				netTail = tempNode;
			}
			netTail->ipaddr = curIP;
			netTail->Data.ID = curID;

			nodeNum++;
			printf("      Generated Node %d: %s (ID:%d)\n", nodeNum, curIPstr, curID);

		}

	}

	/* Variable Re-Initialization */
	fileNum = 0;

	printf("   ** C. File Initialization : Automatic\n");

	printf("      => Input the number of initial files (<%d) : ", ringSize / 4);
	do {
		fflush(stdin);
		scanf("%d", &initFile);
	} while ((initFile < 1) || (initFile > ringSize / 4));

	printf("      * In Automatic Mode, File Name will be random within F0~F%d \n", ringSize - 1);

	while (fileNum < initFile) {
		sameExist = 0;
		ownNodeNo = rand() % nodeNum;

		curName[0] = 'F';
		randFName = rand() % (initFile * ringSize);
		_itoa(randFName, curName + 1, 10);

		tempNode = netHead;
		while (tempNode != NULL) {   /* check the same name till the last node */
			if (tempNode->Data.ownFile.fileNum > 0) {
				for (i = 0; i < tempNode->Data.ownFile.fileNum; i++)
				if (!strcmp(tempNode->Data.ownFile.file[i].Name, curName)) {
					sameExist = 1;   /* Already Exists */
					break;           /* Choose Other */
				}
			}
			tempNode = tempNode->nextNode;
			if (sameExist)
				break;
		}

		if (!sameExist) {
			curKey = str_hash(curName);

			tempNode = netHead;
			while (tempNode != NULL) {   /* till the last node */
				if (tempNode->Data.ownFile.fileNum > 0) {
					for (i = 0; i < tempNode->Data.ownFile.fileNum; i++)
					if (tempNode->Data.ownFile.file[i].Key == curKey) {
						sameExist = 1;  /* Already Exists */
						break;          /* Choose Other */
					}
				}
				tempNode = tempNode->nextNode;
				if (sameExist)
					break;
			}
		}

		if (!sameExist) {

			tempNode = netHead;
			for (i = 0; i < ownNodeNo; i++)
				tempNode = tempNode->nextNode;

			if (tempNode->Data.ownFile.fileNum+1 > nodefmax)  /* nodefmax exceeded -> reassign */
				break;
			tempNode->Data.ownFile.fileNum++;

			strcpy(tempNode->Data.ownFile.file[tempNode->Data.ownFile.fileNum - 1].Name, curName);
			tempNode->Data.ownFile.file[tempNode->Data.ownFile.fileNum - 1].Key = curKey;
			tempNode->Data.ownFile.file[tempNode->Data.ownFile.fileNum - 1].owner = tempNode;

			tempNode->Data.ownFile.file[tempNode->Data.ownFile.fileNum - 1].Data = calloc(FDataMax + 1, sizeof(char));
			strcpy(tempNode->Data.ownFile.file[tempNode->Data.ownFile.fileNum - 1].Data, "File Name is ");
			strcat(tempNode->Data.ownFile.file[tempNode->Data.ownFile.fileNum - 1].Data, curName);

			printf("      Generated File %d: %s (Key:%d) Owner ID: %d\n", ++fileNum, curName, curKey, tempNode->Data.ID);
		}
	}

	printf("-----------------------------------------------------------------\n");
	printf("STEP 2: Construct CHORD Tables\n");

	printf("    A. Construction of CHORD Table \n");

	curNode = netHead;
	i = 0;

	while (curNode != NULL) {   /* till the last node */
		printf("       * Join Node (%d) : %s (ID: %d) \n", i + 1,
			inet_ntoa(curNode->ipaddr), curNode->Data.ID);

		initialize(curNode, netHead);

		stabilize(curNode);

		tempNode = netHead;
		for (j = 0; j <= i; j++) {

			fix_finger(tempNode);

			printf("          - Finger Table (Node %d): Pre(%d) ",
				tempNode->Data.ID, tempNode->Data.chordData.fingerInfo.Pre->Data.ID);
			for (k = 0; k < baseM; k++)
				printf("%d(%d) ", k, tempNode->Data.chordData.fingerInfo.finger[k]->Data.ID);
			printf("\n");

			tempNode = tempNode->nextNode;
		}
		curNode = curNode->nextNode;
		i++;
	}

	printf("    B. Addition of File Information in CHORD Table \n");
	printf("       B1. File Own Information \n");

	curNode = netHead;
	i = 0;
	while (curNode != NULL) {   /* print file own information till the last node */
		for (j = 0; j < curNode->Data.ownFile.fileNum; j++) {
			printf("        (%d) Node (ID = %3d) has %5s (key = %3d).\n", i + 1,
				curNode->Data.ID, curNode->Data.ownFile.file[j].Name, curNode->Data.ownFile.file[j].Key);
			i++;
		}
		curNode = curNode->nextNode;
	}

	printf("       B2. File Reference Information \n");

	curNode = netHead;
	i = 0;
	while (curNode != NULL) {   /* print file ref information till the last node */
		for (j = 0; j < curNode->Data.ownFile.fileNum; j++) {
			tempNode = find_successor(curNode, curNode->Data.ownFile.file[j].Key);
			if (tempNode->Data.chordData.ownFRef.fileNum + 1 > nodefmax) {
				printf("        ==== nodenfmax(=%d) Exceeded! Please increase nodenfmax!\n", nodefmax);
				return 0;
			}
			else
				tempNode->Data.chordData.ownFRef.file[tempNode->Data.chordData.ownFRef.fileNum++] = curNode->Data.ownFile.file[j];

			printf("        (%d) Node (ID = %3d) has reference info. of %5s (key = %3d, owner ID = %3d).\n",
				i + 1, tempNode->Data.ID, curNode->Data.ownFile.file[j].Name, curNode->Data.ownFile.file[j].Key, curNode->Data.ID);
			i++;
		}
		curNode = curNode->nextNode;
	}

	printf("    * CHORD Network Setup Completed!\n\n");
	printf("-----------------------------------------------------------------\n");
	printf("STEP 3: Handling User Selected Commands: \n");

	do {
		do {
			printf("  1) File Search    2) Node Join    3) File Add    0) Quit : ");
			scanf("%d", &USel);
		} while ((USel<0) || (USel>3));

		fflush(stdin);

		if (USel == 0) {
			/* Statistics Information with Greetings */
			break;
		}

		switch (USel) {

		case 1: // File Search
			printf("     (1) File Search\n");

			nodeNum = countNodes();
			printNodes();

			do {
				printf("     1.1 Enter the number of the node searching for a file : ");
				scanf("%d", &USel2);
			} while ((USel2 < 1) || (USel2 > nodeNum));
			fflush(stdin);

			fileNum = countFiles();
			printFiles();
			do {
				printf("     1.2 Enter the number of the file to search for : ");
				scanf("%d", &USel3);
			} while ((USel3 < 1) || (USel3 > fileNum));
			fflush(stdin);

			targetNode = getNode(USel2);
			targetFile = getFile(USel3);

			printf("       - Search file %s (Key=%d) at Node %s (ID=%d)\n",
				targetFile.Name, targetFile.Key, inet_ntoa(targetNode->ipaddr), targetNode->Data.ID);

			foundNode = (nodeType *)calloc(1, sizeof(nodeType));
			Found = lookup(targetNode, targetFile.Key, &foundNode);

			switch (Found) {
			case 1:
				printf("       - The file %s is stored at Node ID %d itself!\n",
					targetFile.Name, targetNode->Data.ID);
				break;
			case 2:
				printf("       - The file %s is not stored at Node ID %d.\n",
					targetFile.Name, targetNode->Data.ID);
				printf("       - Reference info of file %s is at Node ID %d itself!\n",
					targetFile.Name, targetNode->Data.ID);

				for (i = 0; i < targetNode->Data.chordData.ownFRef.fileNum; i++)
				if (targetNode->Data.chordData.ownFRef.file[i].Key == targetFile.Key)
					foundFile = targetNode->Data.chordData.ownFRef.file[i];

				printf("       - Actual file %s is stored at Node %s (ID=%d).\n",
					targetFile.Name, inet_ntoa(foundFile.owner->ipaddr),
					foundFile.owner->Data.ID);
				break;
			default:
				printf("       - The file %s is not stored at Node ID %d.\n",
					targetFile.Name, targetNode->Data.ID);
				printf("       - Reference info of file %s is not at Node ID %d.\n",
					targetFile.Name, targetNode->Data.ID);
				printf("       - The Successor of Key %d : Node ID %d.\n",
					targetFile.Key, foundNode->Data.ID);
				printf("       - Node ID %d has the reference of the file %s.\n",
					foundNode->Data.ID, targetFile.Name);

				for (i = 0; i < foundNode->Data.chordData.ownFRef.fileNum; i++)
				if (foundNode->Data.chordData.ownFRef.file[i].Key == targetFile.Key)
					foundFile = foundNode->Data.chordData.ownFRef.file[i];

				printf("       - The actual file %s is stored at Node %s (ID=%d).\n",
					targetFile.Name, inet_ntoa(foundFile.owner->ipaddr),
					foundFile.owner->Data.ID);
				break;
			}

			break;
		case 2: // Node Join
			printf("     (2) Node Join\n");

			nodeNum = countNodes();
			printNodes();

			if (nodeNum >= ringSize) {
				printf("     - There is NO more remaining space for a new node!\n");
				break;
			}

			do {

				do {
					sameExist = 0;
					fflush(stdin);
					do { // ip address check
						memset(tempIPstr, 0, 16);
						printf("     2.1 Enter the IP address of the joining node : ");
						scanf("%s", tempIPstr);
						fflush(stdin);
					} while (inet_addr(tempIPstr) == -1);

					tempNode = netHead;
					while (tempNode != NULL) {   /* if not the first time */
						if (!strcmp(tempIPstr, inet_ntoa(tempNode->ipaddr))) {
							printf("       - The same node %s already exists!\n", tempIPstr);
							sameExist = 1; /* IP address Already Exists */
							break;         /* Choose Other */
						}
						tempNode = tempNode->nextNode;
					}
				} while (sameExist);

				fflush(stdin);

				tempID = str_hash(tempIPstr);

				sameExist = 0;
				tempNode = netHead;
				while (tempNode != NULL) {   /* if not the first time */
					if (tempID == tempNode->Data.ID) {
						printf("       - The node with the same ID already exists!\n");
						sameExist = 1; /* ID Already Exists */
						break;         /* Choose Other */
					}
					tempNode = tempNode->nextNode;
				}

			} while (sameExist);

			printf("       - Node ID of %s is %d.\n", tempIPstr, tempID);

			curNode = (nodeType *)calloc(1, sizeof(nodeType));

			if (netHead != NULL) {  /* not the first node */
				netTail->nextNode = curNode;
				netTail = curNode;
			}
			else {					/* the first node */
				netHead = curNode;
				netTail = curNode;
			}
			curNode->ipaddr.S_un.S_addr = inet_addr(tempIPstr);
			curNode->Data.ID = tempID;

			printf("     2.2 CHORD Network Connection Update\n");

			result = join(curNode, netHead);

			if (result == -1) {
				printf("  ==== ERROR: join failed! ==== \n");
				tempNode = netHead;
				while (tempNode->nextNode != netTail)
					tempNode = tempNode->nextNode;
				netTail = tempNode;
				netTail->nextNode = NULL;
				free(curNode);
				break;
			}

			// Printing
			printNodes();
			tempNode = netHead;
			while (tempNode != NULL) {
				printf("          - Finger Table (Node %d): Pre(%d) ",
					tempNode->Data.ID,
					tempNode->Data.chordData.fingerInfo.Pre->Data.ID);
				for (i = 0; i < baseM; i++)
					printf("%d(%d) ", i, tempNode->Data.chordData.fingerInfo.finger[i]->Data.ID);
				printf("\n");
				tempNode = tempNode->nextNode;
			}

			printFiles();
			break;

		case 3: // File Add
			printNodes();
			nodeNum = countNodes();

			do {
				do {
					printf("     3.1 Enter the number of the node for adding a file: ");
					scanf("%d", &USel);
					fflush(stdin);
				} while ((USel <= 0) || (USel > nodeNum));

				curNode = getNode(USel);
				if (curNode->Data.ownFile.fileNum + 1 > nodefmax) { /* nodefmax exceeded -> reassign */
					printf("     ===> Error: Node's max file number exceeded. Choose a differen node! \n\n");
					continue;
				}

				printFiles();
				fflush(stdin);

				do {
					printf("     3.2 Enter the name of the file to add: ");
					scanf("%s", curName);
					fflush(stdin);

					tempNode = netHead;
					while (tempNode != NULL) {   /* check the same name till the last node */
						if (tempNode->Data.ownFile.fileNum > 0) {
							for (i = 0; i < tempNode->Data.ownFile.fileNum; i++)
							if (!strcmp(tempNode->Data.ownFile.file[i].Name, curName)) {
								sameExist = 1;   /* Already Exists */
								break;           /* Choose Other */
							}
						}
						tempNode = tempNode->nextNode;
						if (sameExist) {
							printf("     ===> Error: A file with the same name exists! \n\n");
							break;
						}
					}

					if (!sameExist) {
						curKey = str_hash(curName);

						tempNode = netHead;
						while (tempNode != NULL) {   /* till the last node */
							if (tempNode->Data.ownFile.fileNum > 0) {
								for (i = 0; i < tempNode->Data.ownFile.fileNum; i++)
								if (tempNode->Data.ownFile.file[i].Key == curKey) {
									sameExist = 1;  /* Already Exists */
									break;          /* Choose Other */
								}
							}
							tempNode = tempNode->nextNode;
							if (sameExist) {
								printf("     ===> Error: A file with the same key exists! \n\n");
								break;
							}
						}
					}

				} while (sameExist);

				curNode->Data.ownFile.fileNum++;
				strcpy(curNode->Data.ownFile.file[curNode->Data.ownFile.fileNum - 1].Name, curName);
				curNode->Data.ownFile.file[curNode->Data.ownFile.fileNum - 1].Key = curKey;
				curNode->Data.ownFile.file[curNode->Data.ownFile.fileNum - 1].owner = curNode;

				curNode->Data.ownFile.file[curNode->Data.ownFile.fileNum - 1].Data = calloc(FDataMax + 1, sizeof(char));
				strcpy(curNode->Data.ownFile.file[curNode->Data.ownFile.fileNum - 1].Data, "File Name is ");
				strcat(curNode->Data.ownFile.file[curNode->Data.ownFile.fileNum - 1].Data, curName);

				printf("      Generated File: %s (Key:%d) Owner ID: %d\n", curName, curKey, curNode->Data.ID);

				tempNode = find_successor(curNode, curKey);
				if (tempNode->Data.chordData.ownFRef.fileNum + 1 > nodefmax) { /* nodefmax exceeded -> reassign */
					printf("     ===> Error: Node's max file number exceeded. Choose a differen node! \n\n");
					continue;
				}
				else {
					tempNode->Data.chordData.ownFRef.file[tempNode->Data.chordData.ownFRef.fileNum++]
						= curNode->Data.ownFile.file[curNode->Data.ownFile.fileNum - 1];
					printf("        Node (ID = %3d) has reference info. of %5s (key = %3d).\n\n",
						tempNode->Data.ID, curName, curKey);
					break;
				}
			} while (1);


			// Printing
			printNodes();
			printFiles();

			break;
		}

	} while (1);

	return 0;

}

static const unsigned char sTable[256] =
{
    0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9,
    0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28,
    0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53,
    0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2,
    0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8,
    0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90,
    0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76,
    0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d,
    0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18,
    0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4,
    0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40,
    0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5,
    0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2,
    0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8,
    0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac,
    0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
};

#define PRIME_MULT 1717

unsigned int strHash(const char *str)  /* Hash: String to Key */
{
    unsigned int len = sizeof(str);
    unsigned int hash = len, i;


    for (i = 0; i != len; i++, str++) {
        hash ^= sTable[(*str + i) & 255];
        hash = hash * PRIME_MULT;
    }

    return hash % ringSize;
}


int fix_finger(nodeType *curNode)
{
	int i;

	if (curNode == NULL)
		return -1;

	for (i = 1; i<baseM; i++)
		curNode->Data.chordData.fingerInfo.finger[i]
		= find_successor(curNode, modPlus(ringSize, curNode->Data.ID, twoPow(i)));

	return 0;
}


nodeType *find_successor(nodeType *curNode, int IDKey)
{
	nodeType *predNode;

	if (curNode->Data.ID == IDKey)
		return curNode;
	else {
		predNode = find_predecessor(curNode, IDKey);
		return predNode->Data.chordData.fingerInfo.finger[0];
	}
}

nodeType *find_predecessor(nodeType *curNode, int IDKey)
{
	nodeType *tempNode = curNode;

	if (tempNode == tempNode->Data.chordData.fingerInfo.finger[0]) // special case: the initial node
		return tempNode;

	while (!modIn(ringSize, IDKey, tempNode->Data.ID, tempNode->Data.chordData.fingerInfo.finger[0]->Data.ID, 0, 1))
		tempNode = find_closest_predecessor(tempNode, IDKey);

	return tempNode;
}

nodeType *find_closest_predecessor(nodeType *curNode, int IDKey)
{
	int i;

	for (i = baseM - 1; i >= 0; i--) {
		if (curNode->Data.chordData.fingerInfo.finger[i] == NULL) // Actually not necessary
			continue;
		if (modIn(ringSize, curNode->Data.chordData.fingerInfo.finger[i]->Data.ID, curNode->Data.ID, IDKey, 0, 0))
			return curNode->Data.chordData.fingerInfo.finger[i];
	}

	return curNode;
}

/* --------------------------------------------------- */
int lookup(nodeType *curNode, int fileKey, nodeType **foundNode)
{
	int i;
	int Store = 0;


	for (i = 0; i<curNode->Data.ownFile.fileNum; i++)
	if (fileKey == curNode->Data.ownFile.file[i].Key)
		return 1; /* Store the File itself */

	for (i = 0; i<curNode->Data.chordData.ownFRef.fileNum; i++)
	if (fileKey == curNode->Data.chordData.ownFRef.file[i].Key) {
		return 2; /* Store the File Reference itself */
	}

	*foundNode = find_successor(curNode, fileKey);

	return 0; /* Success */
}

void stabilize(nodeType *CurNode)
{
	nodeType *P, *succNode;

	succNode = CurNode->Data.chordData.fingerInfo.finger[0]; /*successor */
	P = succNode->Data.chordData.fingerInfo.Pre; /* predecessor of successor */
	if (P != NULL) {
		if (modIn(ringSize, P->Data.ID, CurNode->Data.ID, succNode->Data.ID, 0, 0)) {
			CurNode->Data.chordData.fingerInfo.finger[0] = P;
			succNode = P;
		}
		else {  // Actually not necessary
			P->Data.chordData.fingerInfo.finger[0] = CurNode;
			notify(CurNode, P);
		}
	}
	notify(succNode, CurNode);
}

void notify(nodeType *askNode, nodeType *targetNode)
{
	nodeType *Pre = askNode->Data.chordData.fingerInfo.Pre;

	if ((Pre == NULL) || (Pre == askNode) || modIn(ringSize, targetNode->Data.ID, Pre->Data.ID, askNode->Data.ID, 0, 0))
		askNode->Data.chordData.fingerInfo.Pre = targetNode;
}


void initialize(nodeType *joinNode, nodeType *helpNode)
{
	joinNode->Data.chordData.fingerInfo.Pre = NULL; /* Pre := NULL */
	joinNode->Data.chordData.fingerInfo.finger = (struct nodeInfo **) calloc(baseM, sizeof(struct nodeInfo *));
	// memory allocation for finger table

	if (helpNode->Data.ID == joinNode->Data.ID) // No Help Node
		joinNode->Data.chordData.fingerInfo.finger[0] = joinNode;
	else
		joinNode->Data.chordData.fingerInfo.finger[0] = find_successor(helpNode, modPlus(ringSize, joinNode->Data.ID, twoPow(0)));
}

int join(nodeType *joinNode, nodeType *helpNode)
/* When there is no help node, helpNode = joinNode */
{
	int result;
	nodeType *tempNode = netHead;

	initialize(joinNode, helpNode);
	result = move_keys(joinNode, joinNode->Data.chordData.fingerInfo.finger[0]);
	if (result == -1)
		return -1;

	stabilize(joinNode);

	tempNode = netHead;
	while (tempNode != NULL) {
		fix_finger(tempNode);
		tempNode = tempNode->nextNode;
	}
	return 0;

}

int move_keys(nodeType *toNode, nodeType *fromNode)
{
	int i, j;

	for (i = 0; i<fromNode->Data.chordData.ownFRef.fileNum; i++) {
		if (modIn(ringSize, toNode->Data.ID, fromNode->Data.chordData.ownFRef.file[i].Key, fromNode->Data.ID, 1, 0)) {
			if (toNode->Data.chordData.ownFRef.fileNum + 1 > nodefmax) {
				printf("==== Error: nodefmax(=%d) limit exceeded! ====\n", nodefmax);
				return -1;
			}
			toNode->Data.chordData.ownFRef.file[toNode->Data.chordData.ownFRef.fileNum]
				= fromNode->Data.chordData.ownFRef.file[i];
			toNode->Data.chordData.ownFRef.fileNum++;

			for (j = i; j < fromNode->Data.chordData.ownFRef.fileNum - 1; j++)
				fromNode->Data.chordData.ownFRef.file[i]
				= fromNode->Data.chordData.ownFRef.file[i + 1];
			fromNode->Data.chordData.ownFRef.fileNum--;
			i--;
		}
	}

	return 0;
}

void printNodes(void)
{
	int i = 0;
	nodeType *tempNode = netHead;

	printf("   - Currently there are %d nods: \n", countNodes());
	while (tempNode != NULL) {
		printf("    (%2d) Node %15s (ID=%3d)\n", i + 1, inet_ntoa(tempNode->ipaddr),
			tempNode->Data.ID);
		i++;
		tempNode = tempNode->nextNode;
	}
	printf("\n");
}

void printFiles(void)
{
	int i = 0, j, k, found;
	nodeType *curNode = netHead, *tempNode;

	printf("   - Currently there are %d files: \n", countFiles());
	while (curNode != NULL) {
		for (j = 0; j < curNode->Data.ownFile.fileNum; j++) {
			tempNode = netHead;
			found = 0;
			while (tempNode != NULL) {
				for (k = 0; k < tempNode->Data.chordData.ownFRef.fileNum; k++) {
					if (curNode->Data.ownFile.file[j].Key == tempNode->Data.chordData.ownFRef.file[k].Key) {
						found = 1;
						break;
					}
				}
				if (found) break;
				tempNode = tempNode->nextNode;
			}
			printf("    (%2d) File %5s (Key=%3d) Owner ID: %3d, Ref Owner ID: %3d\n", ++i, curNode->Data.ownFile.file[j].Name,
				curNode->Data.ownFile.file[j].Key, curNode->Data.ID, tempNode->Data.ID);
		}
		curNode = curNode->nextNode;
	}
	printf("\n");
}

nodeType *getNode(int number)
{
	int i = 0;
	nodeType *tempNode = netHead;

	while (tempNode != NULL) {
		i++;
		if (i == number)
			return tempNode;
		tempNode = tempNode->nextNode;
	}
}

fileType getFile(int number)
{
	int i = 0, j;
	nodeType *tempNode = netHead;

	while (tempNode != NULL) {
		for (j = 0; j < tempNode->Data.ownFile.fileNum; j++) {
			i++;
			if (number == i)
				return tempNode->Data.ownFile.file[j];
		}
		tempNode = tempNode->nextNode;
	}
}

int countNodes(void)
{
	int i = 0;
	nodeType *tempNode = netHead;

	while (tempNode != NULL) {
		i++;
		tempNode = tempNode->nextNode;
	}

	return i;
}

int countFiles(void)
{
	int i = 0;
	nodeType *tempNode = netHead;

	while (tempNode != NULL) {
		i += tempNode->Data.ownFile.fileNum;
		tempNode = tempNode->nextNode;
	}

	return i;
}


int modIn(int modN, int targNum, int range1, int range2, int leftmode, int rightmode)
// leftmode, rightmode: 0 => range boundary not included, 1 => range boundary included   
{
	int result = 0;

	if (range1 == range2) {
		if ((leftmode == 0) || (rightmode == 0))
			return 0;
	}

	if (modPlus(ringSize, range1, 1) == range2) {
		if ((leftmode == 0) && (rightmode == 0))
			return 0;
	}

	if (leftmode == 0)
		range1 = modPlus(ringSize, range1, 1);
	if (rightmode == 0)
		range2 = modMinus(ringSize, range2, 1);

	if (range1  < range2) {
		if ((targNum >= range1) && (targNum <= range2))
			result = 1;
	}
	else if (range1 > range2) {
		if (((targNum >= range1) && (targNum < modN))
			|| ((targNum >= 0) && (targNum <= range2)))
			result = 1;
	}
	else if ((targNum == range1) && (targNum == range2))
		result = 1;

	return result;
}

int twoPow(int power)
{
	int i;
	int result = 1;

	if (power >= 0)
	for (i = 0; i<power; i++)
		result *= 2;
	else
		result = -1;

	return result;
}

int modMinus(int modN, int minuend, int subtrand)
{
	if (minuend - subtrand >= 0)
		return minuend - subtrand;
	else
		return (modN - subtrand) + minuend;
}

int modPlus(int modN, int addend1, int addend2)
{
	if (addend1 + addend2 < modN)
		return addend1 + addend2;
	else
		return (addend1 + addend2) - modN;
}





What I have tried:





What I have tried:

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <windows.h>
#include <process.h> 

#define PRIME_MULT 1717
#define FNameMax 32             /* Max length of File Name */
#define FileMax  32             /* Max number of Files */
#define baseM    6              /* base number */
#define ringSize 64             /* ringSize = 2^baseM */
#define fBufSize 1024           /* file buffer size */

typedef struct {                /* Node Info Type Structure */
	int ID;                     /* ID */
	struct sockaddr_in addrInfo;/* Socket address */
} nodeInfoType;

typedef struct {                /* File Type Structure */
	char Name[FNameMax];        /* File Name */
	int  Key;                   /* File Key */
	nodeInfoType owner;         /* Owner's Node */
	nodeInfoType refOwner;      /* Ref Owner's Node */
} fileRefType;

typedef struct {                    /* Global Information of Current Files */
	unsigned int fileNum;           /* Number of files */
	fileRefType  fileRef[FileMax];  /* The Number of Current Files */
} fileInfoType;

typedef struct {                /* Finger Table Structure */
	nodeInfoType Pre;           /* Predecessor pointer */
	nodeInfoType finger[baseM]; /* Fingers (array of pointers) */
} fingerInfoType;

typedef struct {                /* Chord Information Structure */
	fileInfoType   FRefInfo;    /* File Ref Own Information */
	fingerInfoType fingerInfo;  /* Finger Table Information */
} chordInfoType;

typedef struct {                /* Node Structure */
	nodeInfoType  nodeInfo;     /* Node's IPv4 Address */
	fileInfoType  fileInfo;     /* File Own Information */
	chordInfoType chordInfo;    /* Chord Data Information */
} nodeType;

typedef struct {
	unsigned short msgID;      // message ID
	unsigned short msgType;    // message type (0: request, 1: response)
	nodeInfoType   nodeInfo;   // node address info 
	short          moreInfo;   // more info 
	fileRefType    fileInfo;   // file (reference) info
	unsigned int   bodySize;   // body size in Bytes
} chordHeaderType;             // CHORD message header type


void procRecvMsg(void *);
// thread function for handling receiving messages 

void procPPandFF(void *);
// thread function for sending ping messages and fixfinger 

int recvn(SOCKET s, char *buf, int len, int flags);
// For receiving a file

unsigned strHash(const char *);
// A Simple Hash Function from a string to the ID/key space

int twoPow(int power);
// For getting a power of 2 

int modMinus(int modN, int minuend, int subtrand);
// For modN modular operation of "minend - subtrand"

int modPlus(int modN, int addend1, int addend2);
// For modN modular operation of "addend1 + addend2"

int modIn(int modN, int targNum, int range1, int range2, int leftmode, int rightmode);
// For checking if targNum is "in" the range using left and right modes 
// under modN modular environment 

char *fgetsCleanup(char *);
// For handling fgets function

void flushStdin(void);
// For flushing stdin

void showCommand(void);
// For showing commands

nodeType myNode = { 0 };               // node information -> global variable
SOCKET rqSock, rpSock, flSock, frSock, fsSock, pfSock;
HANDLE hMutex;
int sMode = 1; // silent mode


int main(int argc, char *argv[])
{
	WSADATA wsaData;
	HANDLE hThread[2];
	int exitFlag = 0; // indicates termination condition
	char command[7];
	char cmdChar = '\0';
	int joinFlag = 0; // indicates the join/create status
	char tempIP[16];
	char tempPort[6];
	char fileName[FNameMax + 1];
	char fileBuf[fBufSize];
	char strSockAddr[21];
	struct sockaddr_in peerAddr, targetAddr;
	chordHeaderType tempMsg, bufMsg;
	int optVal = 5000;  // 5 seconds
	int retVal; // return value
	nodeInfoType succNode, predNode, targetNode;
	fileInfoType keysInfo;
	fileRefType refInfo;
	FILE *fp;
	int i, j, targetKey, addrSize, fileSize, numTotal, searchResult, resultFlag;
	int serror = 0;
	/* step 0: Program Initialization  */
	/* step 1: Commnad line argument handling  */
	/* step 2: Winsock handling */
	/* step 3: Prompt handling (loop) */
	/* step 4: User input processing (switch) */
	/* step 5: Program termination */

	/* step 0 */

	

	printf("*****************************************************************\n");
	printf("*         DHT-Based P2P Protocol (CHORD) Node Controller        *\n");
	printf("*                  Ver. 0.5     Nav. 07. 2017                   *\n");
	printf("*****************************************************************\n\n");


	/* step 1: Commnad line argument handling  */

	myNode.nodeInfo.addrInfo.sin_family = AF_INET;

	if (argc != 3) {
		printf("\a[ERROR] Usage : %s <IP Addr> <Port No(49152~65535)>\n", argv[0]);
		exit(1);
	}

	if ((myNode.nodeInfo.addrInfo.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE) {
		printf("\a[ERROR] <IP Addr> is wrong!\n");
		exit(1);
	}

	if (atoi(argv[2]) > 65535 || atoi(argv[2]) < 49152) {
		printf("\a[ERROR] <Port No> should be in [49152, 65535]!\n");
		exit(1);
	}

	myNode.nodeInfo.addrInfo.sin_port = htons(atoi(argv[2]));

	strcpy(strSockAddr, argv[2]);
	strcat(strSockAddr, argv[1]);
	printf("strSoclAddr: %s\n", strSockAddr);
	myNode.nodeInfo.ID = strHash(strSockAddr);

	printf(">>> Welcome to ChordNode Program! \n");
	printf(">>> Your IP address: %s, Port No: %d, ID: %d \n", argv[1], atoi(argv[2]), myNode.nodeInfo.ID);
	printf(">>> Silent Mode is ON!\n\n");


	/* step 2: Winsock handling */

	/* step 3: Prompt handling (loop) */
	do {

		do {
			showCommand();
			printf("CHORD>");
			scanf("%s", &cmdChar, sizeof(char));

			/* step 4: User input processing (switch) */
			switch (cmdChar) {
			case 'c':
				if (joinFlag) {
					printf("\a[ERROR] You are currently in the network; You cannot create the network!\n\n");
					continue;
				}
				joinFlag = 1;
				printf("CHORD> You have created a chord network!\n");

				// fill up the finger table information with myself
				myNode.chordInfo.fingerInfo.Pre = myNode.nodeInfo;

				for (i = 0; i<baseM; i++)
					myNode.chordInfo.fingerInfo.finger[i] = myNode.nodeInfo;

				printf("CHORD> Your finger table has been updated!\n");

				if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
					printf("초기화 실패\n");

				// UDP sockets creation for request and response
				rqSock = socket(AF_INET, SOCK_DGRAM, 0); // for request
				rpSock = socket(AF_INET, SOCK_DGRAM, 0); // for response
				
				
				retVal = setsockopt(rqSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&optVal, sizeof(optVal));// setsockopt = 소켓의 옵션값 설정
				if (retVal == SOCKET_ERROR) {
					printf("\a[ERROR] setsockopt() Error!\n");
					serror = WSAGetLastError();
					printf("%d", serror);
					exit(1);
				}

				if (bind(rpSock, (struct sockaddr*) &myNode.nodeInfo.addrInfo, sizeof(myNode.nodeInfo.addrInfo)) < 0) {
					printf("\a[ERROR] Response port bind failed!\n");
					serror = WSAGetLastError();
					printf("%d", serror);
					exit(1);
				}

				flSock = socket(AF_INET, SOCK_STREAM, 0); // for accepting file down request 

				if (bind(flSock, (SOCKADDR*)&myNode.nodeInfo.addrInfo, sizeof(myNode.nodeInfo.addrInfo)) == SOCKET_ERROR) {
					printf("\a[ERROR] bind() error!\n");
					serror = WSAGetLastError();
					printf("%d", serror);
					exit(1);
				}

				retVal = listen(flSock, SOMAXCONN);
				if (retVal == SOCKET_ERROR) {
					printf("\a[ERROR] listen() error!\n"); // for file sending
					serror = WSAGetLastError();
					printf("%d", serror);
					exit(1);
				}

				// threads creation for processing incoming request message
				hThread[0] = (HANDLE)_beginthreadex(NULL, 0, (void *)procRecvMsg, (void *)&exitFlag, 0, NULL);
				// threads creation for processing sending ping message 
				hThread[1] = (HANDLE)_beginthreadex(NULL, 0, (void *)procPPandFF, (void *)&exitFlag, 0, NULL);

				break;
			case 'j':
				if (joinFlag) {
					printf("\a[ERROR] You are currently in the network; You cannot join again!\n\n");
					continue;
				}
				joinFlag = 1;
				// finger table initialization
				myNode.chordInfo.fingerInfo.Pre.ID = -1;
				for (i = 0; i < baseM; i++)
					myNode.chordInfo.fingerInfo.finger[i].ID = -1;
				
				if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
					printf("초기화 실패\n");

				// UDP sockets creation for request and response
				rqSock = socket(AF_INET, SOCK_DGRAM, 0); // for request
				rpSock = socket(AF_INET, SOCK_DGRAM, 0); // for response

				memset(&peerAddr, 0, sizeof(peerAddr));
				peerAddr.sin_family = AF_INET;

				printf("CHORD> You need a helper node to join the existing network.\n");
				printf("CHORD> If you want to create a network, the helper node is yourself.\n");
				while (1) {
					printf("CHORD> Enter IP address of the helper node: ");
					fgets(tempIP, sizeof(tempIP), stdin);
					fgetsCleanup(tempIP);
					if ((peerAddr.sin_addr.s_addr = inet_addr(tempIP)) == INADDR_NONE) {
						printf("CHORD> \a[ERROR] <IP Addr> %s is wrong!\n", tempIP);
						continue;
					}
					else
						break;
				}

				while (1) {
					printf("CHORD> Enter port number of the helper node: ");
					fgets(tempPort, sizeof(tempPort), stdin);
					fgetsCleanup(tempPort);
					if (atoi(argv[2])>65535 || atoi(argv[2])<49152) {
						printf("CHORD> \a[ERROR] <Port No> should be in [49152, 65535]!\n");
						continue;
					}
					else
						break;
				}
				peerAddr.sin_port = htons(atoi(tempPort));

				if (!memcmp(&myNode.nodeInfo.addrInfo, &peerAddr, sizeof(struct sockaddr_in))) {
					printf("\a[ERROR] Helper node cannot be yourself in Joining!\n\n");
					joinFlag = 0;
					continue;
				}

				// create a joinInfo request message
				memset(&tempMsg, 0, sizeof(tempMsg));
				tempMsg.msgID = 1;
				tempMsg.msgType = 0;
				tempMsg.nodeInfo = myNode.nodeInfo;
				tempMsg.moreInfo = 0;
				tempMsg.bodySize = 0;

				retVal = setsockopt(rqSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&optVal, sizeof(optVal));
				if (retVal == SOCKET_ERROR) {
					printf("\a[ERROR] setsockopt() Error!\n");
					serror = WSAGetLastError();
					printf("%d", serror);
					exit(1);
				}

				if (bind(rpSock, (struct sockaddr *) &myNode.nodeInfo.addrInfo, sizeof(myNode.nodeInfo.addrInfo)) < 0) {
					printf("\a[ERROR] Response port bind failed!\n");
					exit(1);
				}

				// send a joinInfo request message to the helper node
				sendto(rqSock, (char *)&tempMsg, sizeof(tempMsg), 0,
					(struct sockaddr *) &peerAddr, sizeof(peerAddr));
				printf("CHORD> JoinInfo request Message has been sent.\n");

				// receive a joinInfo response message from the helper node
				retVal = recvfrom(rqSock, (char *)&bufMsg, sizeof(bufMsg), 0, NULL, NULL);
				if (retVal == SOCKET_ERROR) {
					if (WSAGetLastError() == WSAETIMEDOUT) {
						printf("\a[ERROR] Request timed out!\n");
						joinFlag = 0;
						continue;
					}
					printf("\a[ERROR] Recvfrom Error!\n");
					joinFlag = 0;
					continue;
				}

				if ((bufMsg.msgID != 1) || (bufMsg.msgType != 1)) { // wrong msg
					printf("\a[ERROR] Wrong Message (Not JoinInfo Response) Received!\n");
					joinFlag = 0;
					continue;
				}

				if (bufMsg.moreInfo == -1) { // failure
					printf("\a[ERROR] JoinInfo Request Failed!\n");
					joinFlag = 0;
					continue;
				}

				printf("CHORD> JoinInfo response Message has been received.\n");

				// decode the joinInfo response message
				succNode = bufMsg.nodeInfo;
				myNode.chordInfo.fingerInfo.finger[0] = succNode;
				printf("CHORD> You got your successor node from the helper node.\n");
				printf("CHORD> Successor IP Addr: %s, Port No: %d, ID: %d\n",
					inet_ntoa(succNode.addrInfo.sin_addr), ntohs(succNode.addrInfo.sin_port), succNode.ID);
			}
		} while (cmdChar != 'q');
		if (cmdChar == 'q') { break; }
	} while (1);

	return 0;
}
void showCommand(void)
{
	printf("CHORD> Enter a command - (c)reate: Create the chord network\n");
	printf("CHORD> Enter a command - (j)oin : Join the chord network\n");
	printf("CHORD> Enter a command - (l)eave : Leave the chord network\n");
	printf("CHORD> Enter a command - (a)dd : Add a file to the network\n");
	printf("CHORD> Enter a command - (d)elete: Delete a file to the network\n");
	printf("CHORD> Enter a command - (s)earch: File search and download\n");
	printf("CHORD> Enter a command - (f)inger: Show the finger table\n");
	printf("CHORD> Enter a command - (i)nfo : Show the node information\n");
	printf("CHORD> Enter a command - (m)ute : Toggle the silent mode\n");
	printf("CHORD> Enter a command - (h)elp : Show the help message\n");
	printf("CHORD> Enter a command - (q)uit : Quit the program\n");

}
static const unsigned char sTable[256] =
{
	0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9,
	0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28,
	0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53,
	0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2,
	0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8,
	0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90,
	0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76,
	0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d,
	0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18,
	0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4,
	0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40,
	0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5,
	0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2,
	0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8,
	0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac,
	0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
};

unsigned strHash(const char *str)
{
	unsigned int len = sizeof(str);
	unsigned int hash = len, i;

	for (i = 0; i != len; i++, str++)
	{
		hash ^= sTable[(*str + i) & 255];
		hash = hash * PRIME_MULT;
	}
	return hash % ringSize;
}

char *fgetsCleanup(char *string)
{
	if (string[strlen(string) - 1] == '\n')
		string[strlen(string) - 1] = '\0';
	else
		flushStdin();

	return string;
}

void flushStdin(void)
{
	int ch;

	fseek(stdin, 0, SEEK_END);
	if (ftell(stdin)>0)
		do
			ch = getchar();
	while (ch != EOF && ch != '\n');
}

void procRecvMsg(void *SOCKET) {

}

void procPPandFF(void *SOCKET) {}

int modPlus(int modN, int addend1, int addend2)
{
	if (addend1 + addend2 < modN)
		return addend1 + addend2;
	else
		return (addend1 + addend2) - modN;
}

int modMinus(int modN, int minuend, int subtrand)
{
	if (minuend - subtrand >= 0)
		return minuend - subtrand;
	else
		return (modN - subtrand) + minuend;
}

int twoPow(int power)
{
	int i;
	int result = 1;

	if (power >= 0)
		for (i = 0; i < power; i++)
			result *= 2;
	else
		result = -1;

	return result;
}

int modIn(int modN, int targNum, int range1, int range2, int leftmode, int rightmode)
{
	int result = 0;

	if (range1 == range2) {
		if ((leftmode == 0) || (rightmode == 0))
			return 0;
	}

	if (modPlus(ringSize, range1, 1) == range2) {
		if ((leftmode == 0) && (rightmode == 0))
			return 0;
	}

	if (leftmode == 0)
		range1 = modPlus(ringSize, range1, 1);

	if (rightmode == 0)
		range2 = modMinus(ringSize, range2, 1);

	if (range1 < range2) {
		if ((targNum >= range1) && (targNum <= range2))
			result = 1;
	}
	else if (range1>range2) {
		if (((targNum >= range1) && (targNum < modN)) || ((targNum >= 0) && (targNum <= range2)))
			result = 1;
	}
	else if ((targNum == range1) && (targNum == range2))
		result = 1;

	return result;
}

推荐答案


这篇关于使用和弦协议,制作p2p网络节点(C)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 14:10