// public void MhProtoClient::DownloadMetadataFromServer(int smd, const char *remote_file, int64_t chunk_size) { int16_t response; char abs_file[2048]; DEBUG("MhProtoClient::DownloadMetadataFromServer()\n"); SndCmd(smd, DOWNLOAD_METADATA); write(smd, &chunk_size, sizeof(int64_t)); int16_t path_size = strlen(remote_file); write(smd, &path_size, sizeof(int16_t)); write(smd, remote_file, path_size); so_read(smd, &response, sizeof(int16_t)); DEBUG("DownloadMetadataFromServer->response : %d\n", response); if (response == MH_FILE_NOT_FOUND) { printf("Remote file not found.\n"); ClearResources(); exit(1); } CopyString(abs_file, AbsoluteFile(remote_file)); StrCat(abs_file, ".mdata"); // Metadata::SaveMetadata only updates, so create "touch" metadata // file first. int fd = open(abs_file , O_WRONLY | O_CREAT, 0000644); close(fd); Metadata metadata; metadata.ReadMetadataHeader(smd); metadata.initControlData(); metadata.SaveMetadata(abs_file); }
static void test_tcp_server(void) { int re; int sd; int reader = 0; char buf[5]; struct sockaddr_in sa; struct sockaddr_in sa2; socklen_t sa_len; printf("[tcp(server)] start\n"); sd = so_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if ( sd < 0 ) { goto error; } DEBUG_PRINT(("server_task: so_socket = %d(%d, %d)\n", sd, MERCD(sd), SERCD(sd))); bzero(&sa, sizeof sa); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(12345); re = so_bind(sd, (struct sockaddr*)&sa, sizeof sa); DEBUG_PRINT(("server_task: so_bind = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error; } re = so_listen(sd, 5); DEBUG_PRINT(("server_task: so_listen = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error; } tk_sig_sem(semid, 1); DEBUG_PRINT(("server_task: server semaphore signaled 1\n")); reader = so_accept(sd, (struct sockaddr*)&sa2, &sa_len); DEBUG_PRINT(("server_task: so_accept = %d(%d, %d)\n", reader, MERCD(reader), SERCD(reader))); if ( reader < 0 ) { goto error; } wait_data(reader); bzero(buf, sizeof buf); re = so_sockatmark(reader); DEBUG_PRINT(("server_task: so_sockatmark = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error; } re = so_read(reader, buf, 4); DEBUG_PRINT(("server_task: so_read = %d(%d, %d), buf = %s\n", re, MERCD(re), SERCD(re), buf)); if ( re < 0 || memcmp(buf, "1234", 4) != 0 ) { goto error; } wait_data(reader); bzero(buf, sizeof buf); re = so_sockatmark(reader); DEBUG_PRINT(("server_task: so_sockatmark = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re < 0 ) { goto error; } re = so_recv(reader, buf, 4, MSG_OOB); DEBUG_PRINT(("server_task: so_recv = %d(%d, %d), buf = %s\n", re, MERCD(re), SERCD(re), buf)); if ( re < 0 || buf[0] != 'a' ) { goto error; } tk_sig_sem(semid2, 1); DEBUG_PRINT(("server_task: server semaphore for break signaled 2\n")); DEBUG_PRINT(("server_task: pre-accept for break\n")); re = so_accept(sd, (struct sockaddr*)&sa2, &sa_len); DEBUG_PRINT(("server_task: so_accept = %d(%d, %d)\n", re, MERCD(re), SERCD(re))); if ( re != EX_INTR ) { goto error; } so_close(reader); so_close(sd); printf("[tcp(server)] OK\n"); return; error: printf("[tcp(server)] FAILED\n"); if ( sd > 0 ) { so_close(sd); } if ( reader > 0 ) { so_close(reader); } tk_del_sem(semid2); return; }
// Private Methods void MhProtoClient::DownloadFileFromServer( int cd_sd, const char *metaFile, const char *localFile) { unsigned char *rcv_buffer = NULL; unsigned char rcv_md5sum[16]; int64_t rcv_dataSize; MD5Utils md5Utils; rcv_buffer = static_cast<unsigned char*>(malloc(MAX_CHUNK_SIZE)); SndCmd(cd_sd, DOWNLOAD_CHUNK); metadata_.LoadMetadata(metaFile); metadata_.WriteMetadataHeader(cd_sd); int fd_download = open(localFile , O_WRONLY | O_CREAT , 0000644); if (fd_download == -1) { perror("open download file "); exit(1); } int64_t chunkNumber = -1; int br = 0; bool sock_error = false; off_t filePos; do { DEBUG("Before lock : %ld - \033[1m\033[32m%d\033[0m\n", i64toLong(chunkNumber), getpid()); sem_->semaphore_get_lock(); metadata_.LoadMetadata(metaFile); chunkNumber = metadata_.getNextPendingChunk(); if (chunkNumber == -1) { sem_->semaphore_release_lock(); break; } metadata_.setChunkStatus(chunkNumber, CH_DOWNLOAD, NULL); metadata_.UpdateControlData(metaFile); DEBUG("Next Pending Chunk : %ld\n", i64toLong(chunkNumber)); sem_->semaphore_release_lock(); // Receive chunk RequestChunk(cd_sd, chunkNumber); DEBUG("Next Pending Chunk-v : %ld\n", i64toLong(chunkNumber)); br = so_read(cd_sd, rcv_md5sum, DIGEST_SIZE); DEBUG("MD5 : <%s>\n", md5Utils.digestToStr(rcv_md5sum)); if (br != DIGEST_SIZE) { sock_error = true; goto update; } br = so_read(cd_sd, (unsigned char*)&rcv_dataSize, sizeof(int64_t)); DEBUG("Data Size : %ld\n", i64toLong(rcv_dataSize)); if (br != sizeof(int64_t)) { sock_error = true; goto update; } br = so_read(cd_sd, rcv_buffer, rcv_dataSize); if (br != rcv_dataSize) { sock_error = true; goto update; } // hex_dump((char*)rcv_buffer,200); filePos = (chunkNumber*metadata_.getChunkSize()); lseek(fd_download, filePos, SEEK_SET); write(fd_download, rcv_buffer, rcv_dataSize); update: sem_->semaphore_get_lock(); metadata_.LoadMetadata(metaFile); if (sock_error) { metadata_.setChunkStatus(chunkNumber, CH_ERROR, rcv_md5sum); chunkNumber = -1; } else { metadata_.setChunkStatus(chunkNumber, CH_OK, rcv_md5sum); } metadata_.UpdateControlData(metaFile); sem_->semaphore_release_lock(); } while (chunkNumber != -1 && *kill_proc_ == 0); close(fd_download); if (rcv_buffer != NULL) free(rcv_buffer); DEBUG("Process: no more chunks to download.\n"); }