int main(int argc,char *argv[]) { port=DEFAULT_PORT; snprintf(userName,USERNAME_LEN,"%s",DEFAULT_USER); int r=0; timeLim=TIMEOUT_SEC; while(1){ opt=getopt(argc,argv,"U:P:T:"); if(opt<0)break; switch(opt){ case'U': snprintf(userName,USERNAME_LEN,"%s",optarg); break; case 'P': port=atoi(optarg); break; case 'T': timeLim=atoi(optarg); break; } } printf("UserName:%s Port:%d BroadcastAddress:%s \n",userName,port,broadcastAddress); r=callHELO(port); int j; if(r==0){//受信なし fprintf(stderr,"Become Server\n"); j=executeAsServer(); }else if(r==1){//受信あり fprintf(stderr,"Become Client\n"); j=executeAsClient(); }else{ exit_errmesg("HELO"); } return 0; }
int callHELO(){ struct sockaddr_in sockAddr; int sock,sel; int optval=1; fd_set mask, readfds; if((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1){//ソケットをDGRAMモードで作成する exit_errmesg("socket()"); } FD_ZERO(&mask);//ビットマスクの準備 FD_SET(sock, &mask); sockAddr.sin_family = AF_INET;//ブロードキャストアドレスの情報をsockaddr_in構造体に格納する sockAddr.sin_port = htons(port); sockAddr.sin_addr.s_addr = inet_addr(limitedBroadcastAddress); if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *)&optval, sizeof(optval)) == -1){ exit_errmesg("setsockopt()"); } int i; for(i=0;i<3;i++){ sendto(sock, "HELO", 5, 0, (struct sockaddr *)&sockAddr, sizeof(sockAddr)); readfds = mask;// 受信データの有無をチェック // timeout.tv_sec = TIMEOUT_SEC; timeout.tv_sec = timeLim; timeout.tv_usec = 0; sel=select( sock+1, &readfds, NULL, NULL, &timeout ); if(sel==-1){ exit_errmesg("select(HELO)"); }else if(sel==0){ printf("Time out[%d th].\n",i+1); continue; }else{ int strsize; socklen_t from_len; from_len = sizeof(from_adrs); if((strsize=recvfrom(sock,Buf,10,0,(struct sockaddr *)&from_adrs, &from_len)) == -1){//form_adrsにIPアドレスを取得 exit_errmesg("recvfrom()"); } close(sock); if(strncmp(Buf,"HERE",4)==0){ return 1; } else return 0; } } close(sock); return 0; }
int init_udpclient() { int sock; /* ソケットをDGRAMモードで作成する */ if((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1){ exit_errmesg("socket()"); } return(sock); }
void set_sockaddr_in(struct sockaddr_in *server_adrs, char *servername, in_port_t port_number ) { struct hostent *server_host; /* サーバ名をアドレス(hostent構造体)に変換する */ if((server_host = gethostbyname( servername )) == NULL){ exit_errmesg("gethostbyname()"); } /* サーバの情報をsockaddr_in構造体に格納する */ memset(server_adrs, 0, sizeof(struct sockaddr_in)); server_adrs->sin_family = AF_INET; server_adrs->sin_port = htons(port_number); memcpy(&(server_adrs->sin_addr), server_host->h_addr, server_host->h_length); }
int main(int argc, char *argv[]) { struct sockaddr_in broadcast_adrs; struct sockaddr_in from_adrs; socklen_t from_len; int sock, count = 0; int broadcast_sw = 1; fd_set mask, readfds; struct timeval timeout; int port = DEFAULT_PORT; char username[L_USERNAME] = "JohnDou"; char s_buf[S_BUFSIZE], r_buf[R_BUFSIZE]; int strsize = 0; packet r_packet; /* コマンドライン引数のチェックおよび使用法の表示 */ if(argc != 3) { fprintf(stderr, "Usage: %s User_name, Port_number\n", argv[0]); exit(EXIT_FAILURE); } sprintf(username, "%s", argv[1]); port = atoi(argv[2]); set_sockaddr_in_broadcast(&broadcast_adrs, (in_port_t)port); sock = init_udpclient(); if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *)&broadcast_sw, sizeof(broadcast_sw)) == 1) { exit_errmesg("setsockopt()"); } FD_ZERO(&mask); FD_SET(sock, &mask); // s_buf にHELLOパケットを格納 create_packet(HELLO, s_buf); strsize = sizeof(s_buf); int i; for(i = 0; i < 3; i++) { Sendto(sock, s_buf, strsize, 0, (struct sockaddr *)&broadcast_adrs, sizeof(broadcast_adrs)); readfds = mask; timeout.tv_sec = TIMEOUT_SEC; timeout.tv_usec = 0; if(select(sock+1, &readfds, NULL, NULL, &timeout) == 0) { count++; printf("Send HELLO packets %d times.\n", count); printf("pct : %s\n", s_buf); if(count == 3) { printf("There are no server, so you are server.\n"); server(username, port); } continue; } // HEREパケットを受信したときの処理 from_len = sizeof(from_adrs); strsize = Recvfrom(sock, r_buf, R_BUFSIZE-1, 0, (struct sockaddr *)&from_adrs, &from_len); r_packet = re_packet(r_buf); if(analize_header(r_packet.header) == HERE) { printf("There are server, so you are client.\n"); client(username, from_adrs); } } return 0; }