질문사항이 있어서 이렇게 올립니다 답변부탁드립니다.
소켓프로그램으로
서버와 클라이언트간 파일을 주고 받으려고 한건데요. 문제가 조그 있어서 이렇게 올립니다.
아래는 소스코드입니다.
서버
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "mydirinfo.h"
#define SOCKADDR_IN struct sockaddr_in
#define SOCKADDR struct sockaddr
#define SV_FILE_NAME "svarlist"
#define DIFF_FILE_NAME "difflist"
#define PORT_NUM 7777
#define LOG_MAX 5
#define BUFF_SIZE 1024
#define DIR_PATH "/var"
int main(int argc, char *argv[])
{
SOCKADDR_IN sAdd, cAdd;
char buf[BUFF_SIZE];
int sFd, cFd;
int cLen, fd;
int recvCount;
// 이것은 제가 라이브러리로 따로 만들어 놓은 함수입니다.
// 해당 디렉토리의 파일 정보를 읽어오는 역할을 하는 함수입니다.
dirInfo(DIR_PATH, SV_FILE_NAME);
if ((sFd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket error");
exit(1);
}
bzero(&sAdd, sizeof(sAdd));
sAdd.sin_family = AF_INET;
sAdd.sin_addr.s_addr = htonl(INADDR_ANY);
sAdd.sin_port = htons(PORT_NUM);
if ((bind(sFd, (SOCKADDR *)&sAdd, sizeof(sAdd))) == -1)
{
perror("bind error");
exit(1);
}
if ((listen(sFd, LOG_MAX)) == -1)
{
perror("listen error");
exit(1);
}
while (1)
{
cLen = sizeof(cAdd);
if ((cFd = accept(sFd, (SOCKADDR *)&cAdd, &cLen)) == -1)
{
perror("accept error");
exit(1);
}
if ((fd = open(SV_FILE_NAME, O_RDONLY)) == -1)
{
perror("file open error");
exit(1);
}
while (1)
{
memset(buf, 0, BUFF_SIZE);
if (read(fd, buf, BUFF_SIZE) > 0)
send(cFd, buf, strlen(buf), 0);
else
break;
}
printf("%s 전송 완료\n\n", SV_FILE_NAME);
close(fd);
// 여기서 클라이언트쪽에서 서버에서 보낸 정보를 모두 읽을때 까지
// 기다리는 코드를 넣어야 할 것 같은데요...
/*
if ((fd = open(DIFF_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC)) == -1)
{
perror("file open error");
exit(1);
}
while (1)
{
memset(buf, 0, BUFF_SIZE);
if((recvCount = recv(cFd, buf, BUFF_SIZE, 0)) > 0)
write(fd, buf, recvCount);
else
break;
}
printf("%s 로 파일받기 완료\n\n", DIFF_FILE_NAME);
*/
close(fd);
close(cFd);
}
}
클라이언트
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "mydirinfo.h"
#include "myfilecompare.h"
#define SOCKADDR_IN struct sockaddr_in
#define SOCKADDR struct sockaddr
#define SV_FILE_NAME "svarlist"
#define CL_FILE_NAME "cvarlist"
#define DIFF_FILE_NAME "difflist"
#define PORT_NUM 7777
#define BUFF_SIZE 1024
#define DIR_PATH "/var"
int main(int argc, char *argv[])
{
SOCKADDR_IN sAdd;
char buf[BUFF_SIZE];
int sFd;
int fd;
int recvCount;
if (argc != 2)
{
printf("Usage : filename serverIPaddress\n");
exit(0);
}
dirInfo(DIR_PATH, CL_FILE_NAME);
if ((sFd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket error");
exit(1);
}
bzero(&sAdd, sizeof(sAdd));
sAdd.sin_family = AF_INET;
sAdd.sin_addr.s_addr = inet_addr(argv[1]);
sAdd.sin_port = htons(PORT_NUM);
if (connect(sFd, (SOCKADDR *)&sAdd, sizeof(sAdd)) == -1)
{
perror("connect error");
exit(1);
}
else
printf("서버와 연결되었습니다.\n\n");
if ((fd = open(SV_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC)) == -1)
{
perror("file open error");
exit(1);
}
while (1)
{
memset(buf, 0, BUFF_SIZE);
if ((recvCount = recv(sFd, buf, BUFF_SIZE, 0)) > 0)
write(fd, buf, recvCount);
else
break;
}
// 제 생각대로라면 서버쪽에서 보낸 파일을 받고서 아래 코드들을 실행하여
// 서버 쪽으로 파일을 보내야 하는데 이 주석 밑으로는 실행이 안되고
// 한없이 기다리는군요.
printf("%s 로 파일받기 완료\n\n", SV_FILE_NAME);
close(fd);
fileCompare(SV_FILE_NAME, CL_FILE_NAME);
if ((fd = open(DIFF_FILE_NAME, O_RDONLY)) == -1)
{
perror("filen open error");
exit(1);
}
while (1)
{
memset(buf, 0, BUFF_SIZE);
if (read(fd, buf, BUFF_SIZE) > 0)
send(sFd, buf, strlen(buf), 0);
else
break;
}
printf("%s 전송 완료\n\n", DIFF_FILE_NAME);
close(fd);
close(sFd);
}
서버쪽에서 파일을 보내고 클라이언트쪽에서는 그 파일을 받아 클라이언트쪽의 파일과 비교하여
다시 서버쪽으로 파일을 보내는 프로그램인데요.
실행시 서버쪽에서 파일은 정상적으로 보내지는데 클라이언트 쪽에서 파일을 받지 못하는군요.(정확히 말하면 파일은 받는거 같은데 서버쪽에서 바로 클라이언트쪽의 파일을 받는 부분으로 넘어가서 클라이언트쪽의 실행이 안돼는것 같습니다.)
서버쪽의 코딩에서 문단주석을 해놓으면(위에서 해놓은대로) 실행은 됩니다.
서버쪽과 클라이언트쪽에서 서로 파일을 주고받으려면 어떤 방법이 없을까요?
답변 부탁드립니다.
답변좀..
부탁드려요.
...........
클라이언트에서 파일을 받는데 사용한 while() 문이 끝나고 그 이후 부분의 코드가 실행되려면 어떻게 되어야 할까요?
현재 짜여져 있는 대로라면 recv() 가 <=0 이여야 while() 문이 종료되는데,
recv() 가 <=0 인 경우는 어떤 경우일지 생각해 보시면 되겠습니다.
--
위에님 그게 문제가 아니라..
... 이제 문제가 2개가
... 이제 문제가 2개가 되었습니다.
서버측에서 send() 의 리턴값을 확신하시면,
서버가 보내지 못했는지, 아니면 클라이언트가 받지 못했는지 판명이 될 테고요.
댓글 다신 분이 지적하셨듯,
클라이언트 쪽의 while 루프의 탈출을 어떻게 할 것인지 매우 심각하게 고민하셔야 합니다.
recv() 로 탈출조건을 만들기는 어렵습니다. 서버가 연결을 끊는다면 몰라도.
코드 적으실 땐
OTL
문제 해결했습니다.
문제는 사소한데 있었군요..
알다가도 모를.. 암튼 답변 감사드립니다.
댓글 달기