2014-12-09 2 views
2

소켓을 통해 파일을 보내고 싶습니다. 그런 다음 세 개의 메시지를 보내려고합니다. 아래의 코드는 작동하지만 첫 문장을 두 번 보내야합니다. 내 질문은 왜? 하나의 문장이 없으면, 수신기 표시 문장 2, 문장 3 및 문장 3. 이 코드의 문제점은 무엇입니까? TCP 프로토콜을 사용하고 있습니다.C 소켓, 파일 다음에 메시지 보내기, TCP

Sender.c

char file_size[256]; 
struct stat file_stat; 
int sent_bytes = 0; 
int fd; 
int offset; 
int remain_data; 

fd = open(FILE_TO_SEND, O_RDONLY); 
if (fd == -1) 
{ 
     fprintf(stderr, "Error opening file --> %s", strerror(errno)); 

     exit(EXIT_FAILURE); 
} 

/* Get file stats */ 
if (fstat(fd, &file_stat) < 0) 
{ 
     fprintf(stderr, "Error fstat --> %s", strerror(errno)); 

     exit(EXIT_FAILURE); 
} 

fprintf(stdout, "File Size: \n%d bytes\n", file_stat.st_size); 

sprintf(file_size, "%d", file_stat.st_size); 

write(sck, file_size, 256); 

char buffer[1024] = ""; 


while (1) { 
    int bytes_read = read(fd, buffer, sizeof(buffer)); 
    if (bytes_read == 0) 
     break; 

    void *p = buffer; 
    while (bytes_read > 0) { 
     int bytes_written = write(sck, p, bytes_read); 
     if (bytes_written <= 0) { 
      // handle errors 
     } 
     bytes_read -= bytes_written; 
     p += bytes_written; 

    } 
} 


char sentence[1024]; 


write(sck, sentence1, 1024); 

write(sck, sentence1, 1024); 

write(sck, sentence2, 1024); 

write(sck, sentence3, 1024); 

Receiver.c

char buffer[1024] = ""; 
int sck = *((int*) arg); 

int file_size; 

read(sck, buffer, 256); 
file_size = atoi(buffer); 

ssize_t len; 
FILE *received_file; 
int remain_data = 0; 


received_file = fopen("plik.pdf", "w"); 
if (received_file == NULL) 
{ 
     fprintf(stderr, "Failed to open file foo --> %s\n", strerror(errno)); 

     exit(EXIT_FAILURE); 
} 

remain_data = file_size; 

while (((len = recv(sck, buffer, 1024, 0)) > 0) && (remain_data > 0)) 
{ 
     fwrite(buffer, sizeof(char), len, received_file); 
     remain_data -= len; 
} 
fclose(received_file); 



read (sck, buffer, 1024); 
printf("%s 1\n", buffer);  

read (sck, buffer, 1024); 
printf("%s 2\n", buffer); 

read (sck, buffer, 1024); 
printf("%s 3\n", buffer); 
+0

파일 끝에 문장의 첫 번째 문장이 있는지 확인하십시오. – Joachim

+0

'write (2)'도'send (2)'도 데이터가 전적으로 보내 졌음을 보장한다. 호출이 신호 처리기 또는 다른 것으로 인터럽트되면 어떻게됩니까? 프로덕션 코드에서는 항상이 시스템 호출의 반환 값을 확인하십시오. – yeyo

답변

2

아무것도 TCP 프로토콜을 할 수 없습니다. 논리에 결함이 있습니다. 데이터를 수신 한 다음 remaining_data를 확인하고 있습니다. 따라서 문장 1은 while 루프에서 수신되고 폐기됩니다.

잠시 동안 recv()를 수정하거나 순서를 변경하려면 본문으로 이동하십시오. 수정 된 반면에

while ((remain_data > 0) && ((len = recv(sck, buffer, 1024, 0)) > 0)) 

, 당신이 RECV()를 호출 remain_data> 0 RECV()가 호출되지 않은 경우에만 경우 remain_data == 0 (게으른 평가). 따라서 while 루프는 파일을받은 직후에 끝나고 문장을받을 준비가됩니다. 귀하의 코드에서 while 루프는 첫 번째 문장을 읽은 다음 remain_data> 0을 효과적으로 체크하여 문장 1을 무시합니다.

+0

고마워, 지금은 효과가있다. – dakolech

관련 문제