#include #include #include #include #include #include #include #include #include #include #include "tools.h" #define SERVERPORT 3081 // the port users will be connecting to #define PORT_MY_ID_LAST_3_DIG 294 #define PORT_PEER_UDP_BASE 4100 #define PORT_OFFSET_PER_PEER 100 #define MY_UDP_PORT(provider_Num) (PORT_PEER_UDP_BASE+PORT_OFFSET_PER_PEER*provider_Num+PORT_MY_ID_LAST_3_DIG) #define BUF_SIZE 100 #define TEMP_BUF_SIZE 100 #define MAXBUFLEN 100 #define MAXDATASIZE 100 struct SGROUP_DATA { int txt_LineNumber;// line number stored in directory.txt char name[4][5]; // group member name unsigned int portnum[4]; // port number int groupNum[4]; // which group belong to char IPaddress[4][16]; // the ip address of each group int g_memberSize[2];//how many members in this group int groupMember[2][4];// the order of each group struct sockaddr_in my_TCP_peer_addr[4]; }; typedef struct SGROUP_DATA SGROUP_DATA; SGROUP_DATA group_data; char* ProviderName[2] = {"provider1","provider2"}; int providerID=0; char OutBuf1[TEMP_BUF_SIZE]; char OutBuf2[TEMP_BUF_SIZE]; char InBuf1[TEMP_BUF_SIZE]; char InBuf2[TEMP_BUF_SIZE]; /************************************************************* void init(void) Func: initialization **************************************************************/ void init(void) { int i,j; group_data.txt_LineNumber = 0; group_data.g_memberSize[0]=0; group_data.g_memberSize[1]=0; for(i = 0; i<2;i++) for(j=0;j<4;j++){ group_data.groupMember[i][j]=9; } } /************************************************************* void assign2DataStructure(int peerNum,struct hostent * p) **************************************************************/ void assign2DataStructure(int peerNum,struct hostent * p) { unsigned short int pnum = group_data.portnum[peerNum]; group_data.my_TCP_peer_addr[peerNum].sin_family = AF_INET; group_data.my_TCP_peer_addr[peerNum].sin_port = htons(pnum); group_data.my_TCP_peer_addr[peerNum].sin_addr = *((struct in_addr *)p->h_addr); memset(&(group_data.my_TCP_peer_addr[peerNum].sin_zero), '\0', 8); } /************************************************************ void rcv_ack(int fd) function: receiving a ack *************************************************************/ void rcv_ack(int fd) { int numbytes; if ((numbytes=recv(fd, InBuf1, 19, 0)) == -1) { perror("ack"); exit(1); } } /************************************************************ void strcatName(void) function:append the sender's name to the string *************************************************************/ void strcatName(void) { memset(OutBuf1, '\0',TEMP_BUF_SIZE); strcat(OutBuf1,ProviderName[providerID]); } /************************************************************ void strcatGroupSize(int size) function: append the group size to the string para: size, group size *************************************************************/ void strcatGroupSize(int size) { strcat(OutBuf1," "); memset(OutBuf2, '\0',TEMP_BUF_SIZE); itostr(OutBuf2, size) ; OutBuf2[1]='\0'; strcat(OutBuf1, OutBuf2); } /************************************************************ void strcatGroupNumber(void) function: append the group number to the string *************************************************************/ void strcatGroupNumber(void) { memset(OutBuf2, '\0',TEMP_BUF_SIZE); itostr(OutBuf2, providerID+1) ; OutBuf2[1]='\0'; strcat(OutBuf1, OutBuf2); } /************************************************************ void sendDataToPeer(int Gnum,int size) function : send the group information to the next peer parameter: Gnum: group number size: group size *************************************************************/ void sendDataToPeer(int Gnum,int size) { int sockfd, numbytes; int i,j; int stop = 0; struct hostent *he; struct sockaddr_in their_addr; /***************************************** * Open a new TCP socket *****************************************/ if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if (connect(sockfd, (struct sockaddr *)&group_data.my_TCP_peer_addr[group_data.groupMember[Gnum][0]], sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } /***************************************** * send message 1 ******************************************/ /* provider name*/ strcatName(); /* group size remained*/ strcatGroupSize(size); if (send(sockfd, OutBuf1, strlen(OutBuf1), 0) == -1) perror("send"); rcv_ack(sockfd); /***************************************** * send message 2 ******************************************/ /* provider name*/ strcatName(); /*welcome message */ strcat(OutBuf1," welcome to group"); /* group number*/ strcatGroupNumber(); if (send(sockfd, OutBuf1, strlen(OutBuf1), 0) == -1) perror("send"); rcv_ack(sockfd); /***************************************** * send rest message ******************************************/ for(i=0; i<4;i++){ if(group_data.groupNum[i]== Gnum+1){ if(stop == 0){ stop = 1;//skip the first one continue; } strcatName(); /*strcat peer name*/ strcat(OutBuf1," "); memcpy(OutBuf2, &group_data.name[i][0],5); OutBuf2[5]='\0'; strcat(OutBuf1, OutBuf2); /*strcat peer port num*/ strcat(OutBuf1," "); memset(OutBuf2, '\0',TEMP_BUF_SIZE); itostr(OutBuf2, group_data.portnum[i]); OutBuf2[5]='\0'; strcat(OutBuf1, OutBuf2); if (send(sockfd, OutBuf1, strlen(OutBuf1), 0) == -1) perror("send"); rcv_ack(sockfd); } } close(sockfd); } int main(int argc, char *argv[]) { int UDP_sockfd; int TCP_sockfd; struct sockaddr_in my_UDP_addr; // connect to server struct sockaddr_in my_TCP_addr;// struct sockaddr_in their_addr; //bootstrap struct sockaddr_in their_addr2; //bootstrap struct hostent *he; int numbytes; int i,j; socklen_t addr_len; FILE *fp; char peerName[5]; addr_len = sizeof(struct sockaddr); init(); /* get the host info */ if ((he=gethostbyname("localhost")) == NULL) { perror("gethostbyname"); exit(1); } /* fork 2 providers*/ if( fork() == 0 ) providerID++; /* open the UDP*/ if ((UDP_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("UDPsocket"); exit(1); } /* create a UDP socket and bind a dedicated port*/ my_UDP_addr.sin_family = AF_INET; // host byte order my_UDP_addr.sin_port = htons(MY_UDP_PORT(providerID)); // short, network byte order my_UDP_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP memset(&(my_UDP_addr.sin_zero), '\0', 8); // zero the rest of the struct if (bind(UDP_sockfd, (struct sockaddr *)&my_UDP_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } /* Try to send the registration data*/ /*provider name*/ strcatName(); /*user name and pwd*/ strcat(OutBuf1," provider spring07"); their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(SERVERPORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct /*send the registration data*/ if ((numbytes = sendto(UDP_sockfd, OutBuf1, strlen(OutBuf1), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1); } /*try to receive file name*/ if ((numbytes = recvfrom(UDP_sockfd, InBuf1, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr2, &addr_len)) == -1) { perror("recvfrom"); exit(1); } InBuf1[numbytes] = '\0'; getStrSegment(InBuf1,InBuf2,2);// the file name is stored at 2nd segment /*Open the file*/ fp = fopen(InBuf2, "r"); if(!fp) printf("open error"); fseek(fp,0,SEEK_SET); /*store all the data scaned from file*/ while(!feof(fp)){ fscanf(fp,"%s %u %s %d\n",&group_data.name[group_data.txt_LineNumber][0], &group_data.portnum[group_data.txt_LineNumber], &group_data.IPaddress[group_data.txt_LineNumber][0], &group_data.groupNum[group_data.txt_LineNumber]); if(group_data.groupNum[group_data.txt_LineNumber]== 1){ group_data.groupMember[0][group_data.g_memberSize[0]]=group_data.txt_LineNumber; group_data.g_memberSize[0]++; } if(group_data.groupNum[group_data.txt_LineNumber]== 2){ group_data.groupMember[1][group_data.g_memberSize[1]]=group_data.txt_LineNumber; group_data.g_memberSize[1]++; } assign2DataStructure(group_data.txt_LineNumber,he); group_data.txt_LineNumber++; } printf("Group %d has %d peer subscribers\n",providerID+1,group_data.g_memberSize[providerID]); /*if group size >0, send the rest data*/ if(group_data.g_memberSize[providerID]>0) sendDataToPeer(providerID,group_data.g_memberSize[providerID]); memcpy(OutBuf1,group_data.name[group_data.groupMember[providerID][0]],5); OutBuf1[5] = '\0'; if(group_data.g_memberSize[providerID]!=0) printf("%s joined group %d\n",OutBuf1,providerID+1); /*send to bootstrap server, to notify it the content provider is done. */ if ((numbytes = sendto(UDP_sockfd, "ack", 4, 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) { perror("sendto"); exit(1); } close(UDP_sockfd); return 0; }