리눅스에서 간단한 파일전송 프로그램 만들기
글쓴이: pchero / 작성시간: 토, 2007/05/05 - 4:49오후
안녕하세요.
몇일동안 혼자 골머리를 썩히다가 용기를 내어 이곳에 글을 올려 봅니다.
현재 리눅스에서 돌아가는 간단한 파일전송 프로그램을 만들고 있습니다. 대충 윤곽을 잡고 코딩을 했는데 마지막에서 머리를 썩힙니다..;;
현재 문제는 파일전송시 받는부분에서의 open() 함수 문제와 segment fault 입니다.
open()를 fopen()으로 대체하고 여러모로 시도를 해 보았으나 안되더군요..
윈도우 프로그래밍책을 참고로 작성을 하였는데..많이 모르겠습니다.
아니면 제가 참고할 수 있는(초보기준..;;) 간단한 예제 코드라도 알려주세요.
고수님들 부탁드립니다.;;
- receiver.c -
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #define BUFSIZE 4096 void err_quit(char *msg) { fputs(msg, stderr); fputc('\n', stderr); exit(1); } int recvn(int s, char *buf, int len) { int received; char *ptr = buf; int left = len; while(left > 0) { received = read(s, buf, sizeof(buf)); if(received == -1) return -1; else if(received == 0) break; left -= received; ptr += received; } return (len - left); } int main(int argc, char *argv[]) { int retval; int listen_sock = socket(PF_INET, SOCK_STREAM, 0); if(listen_sock == -1) err_quit("socket() error"); struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(9000); serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); retval = bind(listen_sock, (struct sockaddr*) &serveraddr, sizeof(serveraddr)); if(retval == -1) err_quit("bind() error"); retval = listen(listen_sock, 5); if(retval == -1) err_quit("listen() error"); int client_sock; struct sockaddr_in clientaddr; int addrlen; char buf[BUFSIZE]; while(1) { addrlen = sizeof(clientaddr); client_sock = accept(listen_sock, (struct sockaddr*) &clientaddr, &addrlen); if(client_sock == -1) err_quit("accept() error"); printf("\n->FileSender connect : IP = %s, Port = %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); char filename[256]; memset(filename, 0, sizeof(filename)); retval = recvn(client_sock, filename, 256); if(retval == -1) { err_quit("recv() error"); close(client_sock); continue; } printf("-> filename : %s\n", filename); int totalbytes; retval = recvn(client_sock, (char *) &totalbytes, sizeof(totalbytes)); if(retval == -1) { err_quit("recv() error"); close(client_sock); continue; } printf("-> filesize : %d\n", totalbytes); FILE *fp = fopen(filename, "wb"); if(fp == NULL) { err_quit("File I/O error"); close(client_sock); continue; } int numtotal = 0; while(1) { retval = recvn(client_sock, buf, BUFSIZE); if(retval == -1) { err_quit("recv() error"); break; } else if(retval == 0) break; else { fwrite(buf, 1, retval, fp); numtotal += retval; } } fclose(fp); if(numtotal == totalbytes) printf("-> File trans complete\n"); else printf("-> File trans failed\n"); close(client_sock); printf("FileSender complete : IP = %s, Port = %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); } close(listen_sock); return 0; }
- sender.c-
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #define BUFSIZE 4096 void err_quit(char *msg) { fputs(msg, stderr); fputc('\n', stderr); exit(1); } int main(int argc, char *argv[]) { int retval; if(argc < 2) { fprintf(stderr, "Usage : %s [Filename] \n", argv[0]); return -1; } int sock; struct sockaddr_in serveraddr; sock = socket(PF_INET, SOCK_STREAM, 0); if(sock == -1) err_quit("socket() error"); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(9000); serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); /*inet_addr("127.0.0.1");*/ retval = connect(sock, (struct sockaddr*) &serveraddr, sizeof(serveraddr)); if(retval == -1) err_quit("connect() error"); FILE *fp = fopen(argv[1], "rb"); if(fp == NULL) err_quit("fopen() error"); char filename[256]; memset(filename, 0, sizeof(filename)); sprintf(filename, argv[1]); retval = write(sock, filename, sizeof(filename)); if(retval == -1) err_quit("write() error"); fseek(fp, 0, SEEK_END); int totalbytes = ftell(fp); retval = write(sock, (char *)&totalbytes, sizeof(totalbytes)); if(retval == -1) err_quit("write() error"); char buf[BUFSIZE]; int numread; int numtotal = 0; rewind(fp); while(1) { numread = fread(buf, 1, BUFSIZE, fp); if(numread > 0) { retval = write(sock, buf, numread); if(retval == -1) err_quit("write() error!"); numtotal += numread; } else if(numread == 0 && numtotal == totalbytes) { printf("file trans complete : %d bytes\n", numtotal); break; } else { err_quit("file I/O error"); } } fclose(fp); close(sock); return 0; }
Forums:
--;
위에서
received = read(s, buf, sizeof(buf));
를
received = read(s, ptr, left);
정도로 바꿔보심이..
recvn 함수가 이상하네요.
received = read(s, buf, sizeof(buf)); 이
received = read(s, ptr, left); 로
=================================
:: how about a cup of tea ? ::
=================================
=================================
:: how about a cup of tea ? ::
=================================
감사합니다..;;;
계속 디버깅만 하다가 안되서 열만 내고 있었는데...;;
너무 간단한곳에 답이 있었네요..;
감사합니다. 복받으세요!
아직 갈길이 멀군요^^
---------------------------------
제일 왼쪽이 저입니다 :)
위에 꺼에서 #include
위에 꺼에서
#include 뒤에 들어갈 함수 좀 갈켜주세요
댓글 달기