int main(int argc, char **argv) { int array_size; int box_size; int num_nodes=0; int layer_n_box; int num_layers; int tmp; int i=0; int j; int num_input_edges; int layer=0; int tmp_num_nodes=0; int *input_edges=NULL; char str[300]; int first,last; FILE *f; if(argc<3) { printf("This program generates the graph of the algorithm for max,min finding in the array.\n"); printf("Parametrs are: %s <array_size> <box_size>\n\n",argv[0]); printf("Box size must be smaller than the array size.\n"); return -1; } array_size=atoi(argv[1]); box_size=atoi(argv[2]); printf("array_size = %d\n",array_size); printf("box_size = %d\n",box_size); f=fopen("graph.grf","w"); if(f==NULL) { printf("Can't create file 'graph.grf'\n"); return -1; } layer_n_box=array_size; while(layer_n_box>1) { tmp=layer_n_box/box_size; if(layer_n_box%box_size!=0) tmp++; layer_n_box=tmp; num_nodes+=layer_n_box; printf("Layer %d: num nodes on this layer is %d\n",i,layer_n_box); i++; } num_layers=i; fprintf(f,"<GRAPH_BEGIN>\n"); fprintf(f," header \"header\"\n"); fprintf(f," root \"\"\n"); fprintf(f," tail \"\"\n"); fprintf(f," num_nodes %d\n",num_nodes); fprintf(f,"<NODES_BEGIN>\n"); layer_n_box=array_size; while(layer_n_box>1) { tmp=layer_n_box/box_size; if(layer_n_box%box_size!=0) tmp++; layer_n_box=tmp; for(i=tmp_num_nodes;i<tmp_num_nodes+layer_n_box;i++) { fprintf(f," <NODE_BEGIN>\n"); fprintf(f," number %d\n",i); fprintf(f," type 0\n"); if(layer==0) { fprintf(f," weight %d\n",box_size); } else { fprintf(f," weight %d\n",get_num_input_edges(i,array_size,box_size)); } fprintf(f," layer %d\n",layer); num_input_edges=get_num_input_edges(i,array_size,box_size); //printf("%d\n",num_input_edges); input_edges=(int *)malloc(num_input_edges*sizeof(int)); if(input_edges==NULL) { printf("Memory error\n"); fclose(f); return -1; } get_input_edges(i,array_size,box_size,num_input_edges,input_edges); fprintf(f," num_input_edges %d\n",num_input_edges); fprintf(f," edges ( "); for(j=0;j<num_input_edges;j++) { fprintf(f,"%d ",input_edges[j]); } fprintf(f,")\n"); free(input_edges); input_edges=NULL; if((layer>0)&&(layer<num_layers-1)) { fprintf(f," num_output_edges 1\n"); fprintf(f," edges ( %d )\n",i); fprintf(f," head \"head_%d\"\n",i); fprintf(f," body \"body\"\n"); fprintf(f," tail \"tail\"\n"); } if(layer==0) { fprintf(f," num_output_edges 1\n"); fprintf(f," edges ( %d )\n",i); fprintf(f," head \"head_%d\"\n",i); fprintf(f," body \"body\"\n"); fprintf(f," tail \"tail_first\"\n"); } if(layer==num_layers-1) { fprintf(f," num_output_edges 0\n"); fprintf(f," edges ( )\n"); fprintf(f," head \"head_%d\"\n",i); fprintf(f," body \"body_last\"\n"); fprintf(f," tail \"tail\"\n"); } fprintf(f," <NODE_END>\n\n"); } tmp_num_nodes+=layer_n_box; //printf("Layer %d: num nodes on this layer is %d\n",layer,layer_n_box); layer++; } fprintf(f,"<NODES_END>\n\n"); fprintf(f," num_edges %d\n\n",num_nodes-1); fprintf(f,"<EDGES_BEGIN>\n"); for(i=0;i<num_nodes-1;i++) { fprintf(f," <EDGE_BEGIN>\n"); fprintf(f," number %d\n",i); fprintf(f," weight %d\n",sizeof(double)); fprintf(f," type GRAPH_NONE\n"); fprintf(f," num_var 3\n"); fprintf(f," num_send_nodes 1\n"); fprintf(f," send_nodes ( %d )\n",i); fprintf(f," num_recv_nodes 1\n"); fprintf(f," recv_nodes ( %d )\n",get_recv_node(i,array_size,box_size)); fprintf(f," <SEND_BEGIN>\n\n"); fprintf(f," <CHUNK_BEGIN>\n"); fprintf(f," name \"min\"\n"); fprintf(f," type GRAPH_DOUBLE\n"); fprintf(f," left_offset \"0\"\n"); fprintf(f," right_offset \"1\"\n"); fprintf(f," <CHUNK_END>\n\n"); fprintf(f," <CHUNK_BEGIN>\n"); fprintf(f," name \"max\"\n"); fprintf(f," type GRAPH_DOUBLE\n"); fprintf(f," left_offset \"0\"\n"); fprintf(f," right_offset \"1\"\n"); fprintf(f," <CHUNK_END>\n\n"); fprintf(f," <CHUNK_BEGIN>\n"); fprintf(f," name \"sum\"\n"); fprintf(f," type GRAPH_DOUBLE\n"); fprintf(f," left_offset \"0\"\n"); fprintf(f," right_offset \"1\"\n"); fprintf(f," <CHUNK_END>\n\n"); fprintf(f," <SEND_END>\n"); fprintf(f," <RECIEVE_BEGIN>\n\n"); fprintf(f," <CHUNK_BEGIN>\n"); fprintf(f," name \"min_array[%d]\"\n",get_node_order_in_box(i,array_size,box_size)); fprintf(f," type GRAPH_DOUBLE\n"); fprintf(f," left_offset \"0\"\n"); fprintf(f," right_offset \"1\"\n"); fprintf(f," <CHUNK_END>\n\n"); fprintf(f," <CHUNK_BEGIN>\n"); fprintf(f," name \"max_array[%d]\"\n",get_node_order_in_box(i,array_size,box_size)); fprintf(f," type GRAPH_DOUBLE\n"); fprintf(f," left_offset \"0\"\n"); fprintf(f," right_offset \"1\"\n"); fprintf(f," <CHUNK_END>\n\n"); fprintf(f," <CHUNK_BEGIN>\n"); fprintf(f," name \"sum_array[%d]\"\n",get_node_order_in_box(i,array_size,box_size)); fprintf(f," type GRAPH_DOUBLE\n"); fprintf(f," left_offset \"0\"\n"); fprintf(f," right_offset \"1\"\n"); fprintf(f," <CHUNK_END>\n\n"); fprintf(f," <RECIEVE_END>\n"); fprintf(f," <EDGE_END>\n\n"); } /* End edge cycle */ fprintf(f,"<EDGES_END>\n"); fprintf(f,"<GRAPH_END>\n"); fclose(f); for(i=0;i<num_nodes;i++) { sprintf(str,"head_%d",i); f=fopen(str,"w"); if(f==NULL) { printf("Can't create file '%s'\n",str); return -1; } fprintf(f," /* Header for the node %d */\n",i); fprintf(f," double min,max,sum;\n"); fprintf(f," int size,i;\n"); if(!get_layer(i,array_size,box_size)) { fprintf(f," double *array;\n"); fprintf(f," double *min_array,*max_array,*sum_array;\n\n"); fprintf(f," FILE *f;\n"); fprintf(f," Vector *vct=NULL;\n"); first=i*box_size; last=(i+1)*box_size-1; if(last>=array_size) last=array_size-1; fprintf(f," size=%d;\n",last-first+1); fprintf(f," vct=new Vector;\n"); fprintf(f," if(vct==NULL)\n"); fprintf(f," {\n"); fprintf(f," printf(\"Memory allocation error!\\n\");\n"); fprintf(f," return -1;\n"); fprintf(f," }\n\n"); fprintf(f," array=(double *)malloc(size*sizeof(double));\n"); fprintf(f," if(array==NULL)\n"); fprintf(f," {\n"); fprintf(f," printf(\"Memory allocation error!\\n\");\n"); fprintf(f," return -1;\n"); fprintf(f," }\n\n"); fprintf(f," min_array=array;\n"); fprintf(f," max_array=array;\n"); fprintf(f," sum_array=array;\n"); fprintf(f," f=fopen(\"vector_%d\",\"r\");\n",i); fprintf(f," if(f==NULL)\n"); fprintf(f," {\n"); fprintf(f," printf(\"Can't open file \\\"vector_%d\\\"\\n\");\n",i); fprintf(f," return -1;\n"); fprintf(f," }\n\n"); fprintf(f," if(vct->fread(f) == -1 )\n"); fprintf(f," {\n"); fprintf(f," printf(\"Can't read vector from file \\\"vector_%d\\\"!\\n\");\n",i); fprintf(f," return -1;\n"); fprintf(f," }\n\n"); fprintf(f," fclose(f);\n"); fprintf(f," for(i=0;i<%d;i++) array[i]=vct->element(i);\n",last-first+1); fprintf(f," delete vct;\n\n"); } else { fprintf(f," double *min_array,*max_array,*sum_array;\n\n"); fprintf(f," size=%d;\n",get_num_input_edges(i,array_size,box_size)); fprintf(f," min_array=(double *)malloc(size*sizeof(double));\n"); fprintf(f," max_array=(double *)malloc(size*sizeof(double));\n"); fprintf(f," sum_array=(double *)malloc(size*sizeof(double));\n"); fprintf(f," if((min_array==NULL)||(max_array==NULL)||(sum_array==NULL))\n"); fprintf(f," {\n"); fprintf(f," printf(\"Memory allocation error!\\n\");\n"); fprintf(f," return -1;\n"); fprintf(f," }\n\n"); } fclose(f); } return 0; }
/* * @brief listen每次accept一个连接,则创建一个线程收取文件,线程的call_back函数即为handler,参数是accept的fd * @param int fd */ int handler(int fd) { char buffer[NET_BUFFER_LEN], encrypt_buffer[NET_BUFFER_LEN]; char *buf_ptr; int recv_len = 0; int send_len = 0; int total_recv_len = 0; int total_send_len = 0; int prefix_len = SYMBOL_LEN + COMMAND_LEN + DATA_LEN + FILL_LEN; int payload_len = 0; int fill_len = 0; int data_len = 0; int continue_flag = 1; q_node_t *node; pthread_detach(pthread_self()); add_count(); node = get_recv_node(); //while recv_len == -1看起来很奇怪,似乎将while变成if更加合理 //但是如果在recv时候被信号中断等待过程,则需要重新recv 使用while可以在recv到数据或者0的时候立即 //退出并进一步判断,在recv返回-1的时候判断errno选择是退出还是继续recv while ((recv_len = recv(fd, (void*)buffer, sizeof(buffer), 0)) == -1) { if (errno == EINTR) continue; else { write_log("Handler,recv:%s\n", strerror(errno)); goto ret; //or just break, and recv_len = -1,program will goto ret at the if condition down there } } if (recv_len == 0) { write_log("Recv 0:client_closed %s\n", strerror(errno)); goto ret; } total_recv_len = recv_len; if (recv_len < prefix_len) { //刚开始收数据时,缓冲区是空的,而本fd连头部信息都没有收完全. write_log("Bad connection,recv command error![recv_len=%u,prefixlen=%u]\n", recv_len,prefix_len); goto ret; } while (continue_flag) { while (total_recv_len < prefix_len) { while ((recv_len = recv(fd, (void*)(buffer+total_recv_len), sizeof(buffer) - total_recv_len, 0)) == -1) { if (errno == EINTR) continue; else { write_log("Recv error:%s\n", strerror(errno)); goto ret; } } total_recv_len += recv_len; if (recv_len == 0) { write_log("recv 0:%s\n", strerror(errno)); goto ret; } } //暂时只解析头部 #ifdef ENCODE_ des_decrypt_n(des_pass_phrase, (const void*)buffer , (void*)encrypt_buffer, prefix_len/ALIGN_LEN); //32BYTE/8BYTE memcpy(buffer,encrypt_buffer,prefix_len); #endif payload_len = *(int*)(buffer + SYMBOL_LEN + COMMAND_LEN); fill_len = *(int*)(buffer + SYMBOL_LEN + COMMAND_LEN + DATA_LEN); data_len = prefix_len + payload_len + fill_len + DATA_END_LEN; if (data_len > sizeof(buffer)) { write_log("data_len[%u] > buffer size[%lu]!!!\ please enlarge your buffer size\n", data_len, sizeof(buffer)); goto ret; } if ((total_recv_len - prefix_len) < (payload_len + fill_len + DATA_END_LEN)) { while ((recv_len = recv(fd, (void*)buffer+total_recv_len, (sizeof(buffer) - total_recv_len), 0)) < (data_len - total_recv_len)) { if (recv_len == -1) { if (errno == EINTR) continue; write_log("Handler,recv:%s\n", strerror(errno)); goto ret; } else if (recv_len == 0) { write_log("Handler,recv 0 :%s\n", strerror(errno)); goto ret; } else total_recv_len += recv_len; } total_recv_len += recv_len; } if (memcmp(SYMBOL, buffer, SYMBOL_LEN) != 0) { write_log("Bad connection, bad symbol![%s]\n", buffer); goto ret; } if (memcmp(C_GET_LOAD, buffer + SYMBOL_LEN, COMMAND_LEN) == 0) { buf_ptr = buffer; memcpy(buf_ptr, SYMBOL, SYMBOL_LEN); //packet symbol buf_ptr += SYMBOL_LEN; memcpy(buf_ptr, C_SHOW_LOAD, COMMAND_LEN); //ask server's load command buf_ptr += COMMAND_LEN; data_len = sizeof(float); fill_len = ALIGN_LEN - sizeof(float); memcpy(buf_ptr, &data_len, DATA_LEN ); buf_ptr += DATA_LEN; memcpy(buf_ptr, &fill_len, FILL_LEN ); buf_ptr += FILL_LEN; //================getload============ FILE *result; char result_buf[TEXT_LINE_LEN]; result = popen("awk 'BEGIN{\"uptime\"|getline; print $11;}'","r"); fread(result_buf,sizeof(char),sizeof(result_buf),result); pclose(result); float server_load = atof(result_buf); //============================ memcpy(buf_ptr, &server_load, data_len); buf_ptr += data_len; memset(buf_ptr, 0x0, fill_len); buf_ptr += fill_len; memcpy(buf_ptr,DATA_END,DATA_END_LEN); buf_ptr += DATA_END_LEN; #ifdef ENCODE_ des_encrypt_n(des_pass_phrase, (const void*)buffer , (void*)encrypt_buffer, (buf_ptr - buffer)/ALIGN_LEN); //32BYTE/8BYTE memcpy(buffer, encrypt_buffer, sizeof(buffer)); #endif //sent to client send_len = 0; total_send_len = 0; data_len = buf_ptr - buffer; while ((send_len = send(fd, buffer+total_send_len, (data_len-total_send_len), 0) ) < (data_len - total_send_len) ) { if (send_len == -1) { if (errno == EINTR) continue; write_log("Send load: send error:%s\n", strerror(errno)); goto ret; } else total_send_len += send_len; } total_send_len += send_len; goto ret; } if (memcmp(C_SEND_DATA, buffer + SYMBOL_LEN, COMMAND_LEN) == 0) { //解析数据体 #ifdef ENCODE_ des_decrypt_n(des_pass_phrase, (const void*)(buffer+prefix_len), (void*)encrypt_buffer, (data_len - prefix_len)/ALIGN_LEN); //32BYTE/8BYTE memcpy(buffer + prefix_len, encrypt_buffer, data_len - prefix_len); #endif buf_ptr = buffer + prefix_len; store_result_t *t1; store_result_t *tmp; int effctive_size = sizeof(store_result_t) - sizeof((store_result_t*)0); //=========================================== while ((buf_ptr - (buffer + prefix_len)) < payload_len) { t1 = (store_result_t*)buf_ptr; //将这批数据挂在recvlink上 tmp = get_mem(); memcpy(tmp, t1, effctive_size); tmp->next = NULL; buf_ptr += effctive_size; if (node->recv_link == NULL) node->recv_link = tmp; else { tmp->next = node->recv_link; node->recv_link = tmp; } file_recv_node_len[node->number]++ ; } //============================================ buf_ptr += fill_len;//跳到后续数据标识符 //若为其他(应该是"DATA_END") 则可以退出,若为CONTINU,则继续接收 uint32_t packet_len = prefix_len + payload_len + fill_len + DATA_END_LEN; //printf("\t\t%u,%u\n",total_recv_len,packet_len); if (memcmp(buf_ptr, CONTINUE, DATA_END_LEN) == 0) { //有后续数据 buf_ptr += DATA_END_LEN; if ((buf_ptr - buffer) == sizeof(buffer)) { //buffer收满了,则重新收 recv_len = 0; total_recv_len =0; continue_flag = 1; } else if (total_recv_len == packet_len) { //如果接收到了一个完整的数据分段,则重新接收 recv_len = 0; total_recv_len = 0; continue_flag = 1; } else { //如果缓冲区中有后续包的分段,则前移动,因为这些数据没有解密,所以直接移动 memcpy(encrypt_buffer, buf_ptr, total_recv_len - packet_len); memcpy(buffer, encrypt_buffer, total_recv_len - packet_len); recv_len = total_recv_len - packet_len; total_recv_len = recv_len; continue_flag = 1; } } else continue_flag = 0; //no more data transmitted }//send data }//while continue //store_data int status = write_file(node->recv_link, file_recv_node_len[node->number]); if(status == 0) { //echo DATA__OK to client; buf_ptr = buffer; memcpy(buf_ptr, SYMBOL, SYMBOL_LEN); //packet symbol buf_ptr += SYMBOL_LEN; memcpy(buf_ptr, C_DATA_OK, COMMAND_LEN); //ask server's load command buf_ptr += COMMAND_LEN; memset(buf_ptr, 0x0, DATA_LEN + FILL_LEN); buf_ptr += (DATA_LEN + FILL_LEN); memcpy(buf_ptr,DATA_END,DATA_END_LEN); buf_ptr += DATA_END_LEN; #ifdef ENCODE_ des_encrypt_n(des_pass_phrase, (const void*)buffer , (void*)encrypt_buffer, (buf_ptr - buffer)/ALIGN_LEN); //32BYTE/8BYTE memcpy(buffer,encrypt_buffer,sizeof(buffer)); #endif //sent to client send_len = 0; total_send_len = 0; data_len = buf_ptr - buffer; while ((send_len = send(fd, buffer+total_send_len, (data_len-total_send_len), 0)) < (data_len - total_send_len)) { if (send_len == -1) { if (errno == EINTR) continue; write_log("Send load: send error:%s\n", strerror(errno)); goto ret; } else total_send_len += send_len; } total_send_len += send_len; } ret: recycle_recv_node(node); sub_count(); pthread_mutex_lock(&thread_count_mutex); pthread_cond_signal(&thread_count_cond); pthread_mutex_unlock(&thread_count_mutex); close(fd); pthread_exit(0); return 0; }