#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define NAME_SIZE 50
#define BUF_SIZE 1024
void ErrorHandling(char *message);
int main(int argc, char *argv[])
{
int serv_sock, clnt_sock;
struct sockaddr_in serv_adr, clnt_adr;
socklen_t clnt_adr_sz;
FILE *ifp;
char namebuffer[NAME_SIZE]; //파일이름이 들어가는 문자열(배열)
char filebuffer[BUF_SIZE]; //파일 전송용 버퍼
int name_len;
int idx, c;
if (argc != 2)
{
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if (serv_sock == -1)
error_handling("socket() error");
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_adr.sin_port = htons(atoi(argv[1]));
if (bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1)
ErrorHandling("bind() error");
if (listen(serv_sock, 5) == -1)
ErrorHandling("listen() error");
clnt_adr_sz = sizeof(clnt_adr);
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz); //클라이언트와 연결할 소켓 생성
read(serv_sock, &name_len, 4); //클라이언트가 보낸 데이터의 4바이트를 꺼내 int형 변수에 저장한다
printf("파일이름의 길이: %d\n", name_len);
read(serv_sock, namebuffer, NAME_SIZE); //소켓에서 데이터(파일이름)를 filename으로 가져온다
char* filename = (char*)malloc(sizeof(char) * name_len);
idx = 0;
while (1)
{
if (namebuffer[idx] == '\0')
{
filename[idx] = '\0';
break;
}
filename[idx] = namebuffer[idx];
idx++;
}
printf("요청된 파일: %s", filename);
ifp = fopen(filename, "rb");
/* 파일을 데이터 전송 배열에 담아 보내기 */
idx = 0;
while ((c = getc(ifp) != EOF) && (idx <= BUF_SIZE))
{
filebuffer[idx] = c;
idx++;
}
fclose(ifp);
write(clnt_sock, filebuffer, sizeof(BUF_SIZE));
close(clnt_sock);
close(serv_sock);
free(filename);
return 0;
}
void ErrorHandling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
--------------------윈도우즈---------------------------------
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#define NAME_SIZE 50
#define BUF_SIZE 1024
void ErrorHandling(char *message);
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET hServSock, hClntSock;
SOCKADDR_IN servAdr, clntAdr;
int clntAdrSize;
FILE *ifp;
char namebuffer[NAME_SIZE]; //파일이름이 들어가는 문자열(배열)
char filebuffer[BUF_SIZE]; //파일 전송용 버퍼
int name_len;
int idx, c;
if (argc != 2)
{
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
ErrorHandling("WSAStartup() error!");
hServSock = socket(PF_INET, SOCK_STREAM, 0);
if (hServSock == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&servAdr, 0, sizeof(servAdr));
servAdr.sin_family = AF_INET;
servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
servAdr.sin_port = htons(atoi(argv[1]));
if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
ErrorHandling("bind() error");
if (listen(hServSock, 5) == SOCKET_ERROR)
ErrorHandling("listen() error");
clntAdrSize = sizeof(clntAdr);
hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &clntAdrSize); //클라이언트와 연결할 소켓 생성
recv(hClntSock, &name_len, 4, 0); //클라이언트가 보낸 데이터의 4바이트를 꺼내 int형 변수에 저장한다
printf("파일이름의 길이: %d\n", name_len);
recv(hClntSock, namebuffer, NAME_SIZE, 0); //소켓에서 데이터(파일이름)를 filename으로 가져온다
char* filename = (char*)malloc(sizeof(char) * name_len);
idx = 0;
while (1)
{
if (namebuffer[idx] == '\0')
{
filename[idx] = '\0';
break;
}
filename[idx] = namebuffer[idx];
idx++;
}
printf("요청된 파일: %s", filename);
ifp = fopen(filename, "rb");
/* 파일을 데이터 전송 배열에 담아 보내기 */
idx = 0;
while ( (c = getc(ifp) != EOF) && (idx <= BUF_SIZE) )
{
filebuffer[idx] = c;
idx++;
}
fclose(ifp);
send(hClntSock, filebuffer, sizeof(BUF_SIZE), 0);
closesocket(hClntSock);
closesocket(hServSock);
WSACleanup();
free(filename);
return 0;
}
void ErrorHandling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
파일이름 제대로 가는 건 확인했는데 윈도우즈에서는 디버그하면 파일포인터가 null로 뜨고
디버그한걸 다른데서 복사하고 프롬프트 창에서 열면 오류가 뜨면서 종료됩니다.
리눅스에서 하니까 클라이언트에서 파일이름을 입력하기 전에 read를 하는지 파일이름을 빈 칸으로 출력하고 세그멘테이션 오류라고 뜨더군요.
도대체 무엇을 잘못한 것인지요?
클라이언트 소켓한테서 읽어야지
왜 서버소켓에 대고 읽고있음 그러니 읽힐리가;;
윈도우에서 왜 파일이 안열리는진 모르겠다 그파일이 없거나 공백까지 같이받거나 뭐 그런거 확인해보셈 소켓엔 문제없는듯
헉 진짜 서버소켓 읽고있네요...알려주셔서 감사합니다.