리눅스에서 간단한 파일전송 프로그램 만들기
글쓴이: 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 뒤에 들어갈 함수 좀 갈켜주세요
댓글 달기