本文介绍了使用和弦协议,制作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)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!