2013-09-01 2 views
2

UDP를 사용하여 서버 클라이언트 파일을 전송해야합니다. 클라이언트가 보낸 메시지를받는 기본 서버를 만들었습니다. 그게 다야. 이제 주요 부분을 제공 : -C에서 UDP를 사용하는 서버 클라이언트 파일 전송

1. The message sent by client is the name of file . 
2. Now the server checks whether there exists this file or not . 
3. If there exists it sends the file to the client and it also keeps the count of the  number of requests of file made by the client . 

나는이 새로운 오전과 내가 어떻게 더 이상 진행하는 그것을 얻을하지 않습니다. 여기

내가 프로그램을 편집하고 새로운 버퍼 file_buffer을 만든

#include <stdio.h> 
#include <errno.h> 
#include <sys/socket.h> 
#include <resolv.h> 
#include<netinet/in.h> 
#include<sys/types.h> 



int main() 
{ 
    char buff[2000]; 
    int sockfd,connfd,len; 

struct sockaddr_in servaddr,cliaddr; 

// create socket in client side 
sockfd = socket(AF_INET, SOCK_DGRAM, 0); 

if(sockfd==-1) 
{ 
    printf(" socket not created in client\n"); 
    exit(0); 
} 
else 
{ 
    printf("socket created in client\n"); 
} 


bzero(&servaddr, sizeof(servaddr)); 

servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr = INADDR_ANY; // ANY address or use specific address 
servaddr.sin_port = htons(7802); // Port address 


    printf("Type ur UDP client message\n"); 
    scanf("%s",buff); 

// send msg to server 

sendto(sockfd, buff, strlen(buff), 0, 
      (struct sockaddr *)&servaddr, sizeof(struct sockaddr)); 
     char file_buffer[2000]; 

    if (recvfrom(sockfd,file_buffer,2000,0, (struct sockaddr *)&servaddr, sizeof(struct sockaddr))<0) 
    { 
     printf("error in recieving the file\n"); 
     exit(1); 
    } 

    char new_file[]="copied"; 
    strcat(new_file,buff); 
    FILE *fp; 
    fp=fopen(new_file,"w+"); 
    if(fwrite(file_buffer,1,sizeof(file_buffer),fp)<0) 
    { 
     printf("error writting file\n"); 
     exit(1); 
    } 


    //close client side connection 
    close(sockfd); 

return(0); 
} 

클라이언트 코드 서버 코드 여기

#include<sys/socket.h> 
#include<arpa/inet.h> 
#include<stdio.h> 
#include<unistd.h> 
#include<fcntl.h> 
#include<sys/types.h> 
#include<string.h> 




int main() 
{ 

    char buff[2000]; 
    char file_buffer[2000]; 
    int sd,connfd,len; 

    struct sockaddr_in servaddr,cliaddr; 

    sd = socket(AF_INET, SOCK_DGRAM, 0); 

    if(sd==-1) 
    { 
     printf(" socket not created in server\n"); 
     exit(0); 
    } 
    else 
    { 
     printf("socket created in server\n"); 
    } 

    bzero(&servaddr, sizeof(servaddr)); 

    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = INADDR_ANY; 
    servaddr.sin_port = htons(7802); 

    if (bind(sd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) 
    printf("Not binded\n"); 
    else 
    printf("Binded\n"); 



    len=sizeof(cliaddr); 

    recvfrom(sd,buff,1024,0, 
    (struct sockaddr *)&cliaddr, &len); 

    printf("%s\n",buff); 
    /* */ 
    FILE *fp; 
    fp=fopen(buff,"r"); 
    if(fp==NULL) 
    { 
     printf("file does not exist\n"); 
    } 

    fseek(fp,0,SEEK_END); 
    size_t file_size=ftell(fp); 
    fseek(fp,0,SEEK_SET); 
    if(fread(file_buffer,file_size,1,fp)<=0) 
    { 
     printf("unable to copy file into buffer\n"); 
     exit(1); 
    } 
    if(sendto(sd,file_buffer,strlen(file_buffer),0, (struct sockaddr *)&cliaddr, &len)<0) { 
    printf("error in sending the file\n"); 
    exit(1); 
    } 
    bzero(file_buffer,sizeof(file_buffer)); 


    /* */ 
    close(sd); 

    return(0); 
} 

이다, 서버는 파일에서 데이터를 읽고에 기록 그것과 클라이언트에게 보내십시오, 다른 끝 클라이언트에 데이터를 받고이 파일의 사본을 만들고 그것에 쓰십시오. 그러나 컴파일 할 때 파일을 쓸 때 오류가 발생합니다 : (

+0

수신자가 발신자가 보낸 데이터를 더 읽지 않으려면 확인해야합니다. 그렇지 않으면 수신자가 블록하여 절대 도착하지 않는 데이터를 영원히 기다릴 수 있습니다. 데이터의 양이 일정하지 않거나 미리 알려지지 않은 경우 최소한의 종류의 프로토콜을 구현하지 않습니다. – alk

답변

1

두 가지 모두 로직을 확장해야합니다 기본적으로 서버 코드의 경우 파일 이름으로 buff를 사용하여 파일이 존재하는지 확인하십시오. "fopen (buff,"r ")"-이 값이 NULL을 반환하면 파일이 존재하지 않으며이 경우 파일이 존재하지 않는다는 메시지를 클라이언트에 보내려는 경우가 있습니다 :

파일이 존재하면
FILE *istream; 
strncpy(fileName, buff, ret_len + 1); 
if ((istream = fopen(fileName, "r")) == NULL){ 
    printf ("file non-existant!\n"); 
    strncpy(buff, "Does not Exist", strlen("Does Not Exist")); 
} else { 
    printf ("file exists!\n"); 
    strncpy(buff, "Does Exist", strlen("Does Exist")); 
    fclose (istream); 
} 

ret_len = sendto(sd, buff, strlen(buff), 0, (struct sockaddr *)&cliaddr, sizeof(struct sockaddr)); 
if (ret_len < 0) { 
fprintf(stderr, "sendto() failed [ret value: %d]\n", ret_len); 
return -1; 
} 

, 다음 파일을 읽고 파일에 내용을 보낼 수 있습니다.

클라이언트를 서버에서()는에 recvfrom을 수행해야는 버퍼 t을 전송 후 서버! 이 같은. 숫자 값 (-1 또는 0)을 사용하여 파일이 존재하는지 여부를 나타낼 수 있습니다. 파일이 존재한다면 초기 파일에 파일 길이를 전달할 수 있습니다. 이렇게하면 클라이언트는 읽어야하는 데이터의 양을 알 수 있습니다.

// send msg to server 
sendto(sockfd, buff, strlen(buff) + 1, 0, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)); 

// recveive from server 
ret_len = recvfrom(sockfd, buff, 1024, 0, NULL, 0); 
printf("Received from server: %s \n",buff); 

if (strncmp(buff, "Does not Exist", strlen("Does not Exist")) == 0) 
    printf("File does not exist\n"); 
else if (strncmp(buff, "Does Exist", strlen("Does Exist")) == 0) 
    printf("File does exist\n"); 
else 
    printf("Unknown message\n"); 

btw 위의 코드에서 NUL 문자를 설명하기 위해 1을 추가해야합니다. 또한이 단계가 완료되면 클라이언트 코드는 recvfrom()을 루프에서 호출하여 이전 단계에서 전달 된대로 서버에서 데이터를 수신해야합니다.

파일이 너무 크면 보내려는 메시지만큼 읽는 것이 좋습니다. UDP를 사용하면 최대 64K까지 전송할 수 있지만 이상적으로는 최대 1 개의 MUT 만 전송해야합니다 1500 바이트).

+1

'scanf()'는 "문자열"을 스캔 할 때'0 '종결자를 추가합니다. 나중에 하나 추가 할 필요가 없습니다. – alk

+0

@alk, 맞습니다 - 고마워요! –

+0

직접 해보려고했지만 프로그램이 작동하지 않습니다. 너 나 좀 도와 줄래? – user2714823

0

서버가 FTP 서버처럼 동작하도록 하시겠습니까?

클라이언트에서 파일 이름을받은 후 파일 이름이 존재하는지 확인하십시오. What's the best way to check if a file exists in C? (cross platform)을 참조하십시오. 그런 다음 파일을 열고 버퍼에 버퍼 (예 : 한 번에 200 바이트)를 클라이언트에 보냅니다. 클라이언트는 즉시이를 수신하여 이라는 새 파일에 파일 이름을 작성합니다.

1

자신의 클라이언트/서버를 개발해야하는지 또는 다른 서버를 사용할 수 있는지 확실하지 않았습니다. UDT, UFTP, Tsunami-UDP, 심지어는 Google QUIC과 같은 몇 가지 오픈 소스 UDP 기반 파일 전송 시스템이 있습니다.

관련 문제