#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를 하는지 파일이름을 빈 칸으로 출력하고 세그멘테이션 오류라고 뜨더군요.


도대체 무엇을 잘못한 것인지요?