[socket programming] udp를 이용한 파일 전송 프로그램
2020. 12. 11. 16:47ㆍCS/네트워크
server 코드 (UDPserver.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#define BUFSIZE 1024
void error_handling(char *message);
int main(int argc, char **argv){
FILE* file;
int sd;
char file_name[BUFSIZE];
char buf[BUFSIZE];
int buf_len;
int filename_len;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
int clnt_addr_size = sizeof(clnt_addr);
if(argc!=2){
printf("UDP server %s <port_num>\n", argv[0]);
exit(1);
}
sd = socket(PF_INET, SOCK_DGRAM, 0);
if(sd == -1)
error_handling("socket() error!");
struct timeval optVal = {5,0};
int optLen = sizeof(optVal);
if(setsockopt(sd,SOL_SOCKET,SO_RCVTIMEO,&optVal, optLen) == -1){
error_handling("setsockopt error\n");
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_addr.sin_port=htons(atoi(argv[1]));
if(bind(sd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1)
error_handling("bind() error");
int i;
for(i=0; i < 30; i++){
filename_len = recvfrom(sd,file_name,BUFSIZE,0,(struct sockaddr*)&clnt_addr, &clnt_addr_size);
file = fopen(file_name,"wb");
clnt_addr_size = sizeof(clnt_addr);
sleep(1);
}
while(buf_len = recvfrom(sd,buf,BUFSIZE,0,(struct sockaddr*)&clnt_addr,&clnt_addr_size)>0){
fwrite(buf,sizeof(char), buf_len,file);
sendto(sd,buf,buf_len,0,(struct sockaddr*)&clnt_addr,sizeof(clnt_addr));
if(buf_len == 0)
break;
}
fclose(file);
close(sd);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
client 코드 (UDPclient.c)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#define BUFSIZE 1024
void error_handling(char *message);
int main(int argc, char **argv){
int sock;
int addr_size;
struct sockaddr_in serv_addr;
struct sockaddr_in from_addr;
if(argc!=4){
printf("Usage %s <IP> <port> <file name>\n", argv[0]);
exit(1);
}
sock = socket(PF_INET, SOCK_DGRAM,0);
if(sock == -1)
error_handling("UDP socket error");
struct timeval optVal = {5, 0};
int optLen = sizeof(optVal);
if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &optVal, optLen) == -1){
error_handling("setsockopt error\n");
}
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
serv_addr.sin_port = htons(atoi(argv[2]));
addr_size = sizeof(from_addr);
int total_bufnum;
long filesize;
char buf[BUFSIZE];
int sendlength;
int sendbuf = 0;
int success;
FILE* file; //파일
if((file = fopen(argv[3], "rb")) == NULL) { //argv[3]의 파일을 open
printf("Error");
exit(1);
}
if(file == NULL){
printf("File is not exit");
exit(1);
}
fseek(file, 0, SEEK_END); //파일의 맨 마지막으로 이동
filesize = ftell(file); //파일 위치 값을 리턴 (현재 파일 마지막 위치를 리턴)
fseek(file, 0, SEEK_SET); //파일 제일 처음으로 이동
int i = 0;
for(i = 0; i < 30; i++){
sendto(sock,argv[3] ,strlen(argv[3]),0,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
sleep(5);
}
while((sendlength = fread(buf, sizeof(char), sizeof(buf), file) > 0)) {
sendto(sock,buf ,sendlength,0,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
}
printf("send file done\n");
close(sock);
return 0;
}
void error_handling(char* message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}
server 쪽은 ./UDPserver <port num>
client 쪽은 ./UDPclient <ip addr> <port num> <file name>
으로 실행하면 파일 이름과 파일 내용 일부는 전송이 되지만 전체가 제대로 전송은 되지 않는것을 알 수 있다.
'CS > 네트워크' 카테고리의 다른 글
[socket programming] 간단한 webserver 구현 (0) | 2020.12.11 |
---|---|
[socket programming] tcp 이용한 파일 전송 프로그램 (0) | 2020.12.11 |
socket programming #1 (0) | 2020.12.09 |