#include <iostream>
#include <fstream>
#include <cstring>
#include <sstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/stat.h>
int main() {
// 1. 서버 소켓 생성 및 옵션 설정
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("소켓 생성 실패");
return -1;
}
int opt = 1;
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
perror("옵션 설정 실패");
return -1;
}
// 2. 서버 주소 설정 (모든 인터페이스, 포트 8080)
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
perror("바인딩 실패");
return -1;
}
if (listen(server_fd, 3) < 0) {
perror("리스닝 실패");
return -1;
}
std::cout << "HTTP 서버가 포트 8080에서 대기 중입니다.\n";
while (true) {
// 3. 클라이언트 연결 수락
int addrlen = sizeof(address);
int client_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen);
if (client_socket < 0) {
perror("연결 수락 실패");
continue;
}
std::cout << "클라이언트 연결됨.\n";
// 4. HTTP 요청 읽기 (여기서는 요청 내용을 간단히 읽어 출력)
char request_buffer[1024] = {0};
read(client_socket, request_buffer, sizeof(request_buffer) - 1);
std::cout << "요청 내용:\n" << request_buffer << "\n";
// 5. 전송할 파일 열기
const char* filename = "/Users/yeongjae/Desktop/y_downloader/y_downloader/myproject.unitypackage";
std::ifstream file(filename, std::ios::binary);
if (!file) {
std::string not_found = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
send(client_socket, not_found.c_str(), not_found.size(), 0);
close(client_socket);
continue;
}
// 6. 파일 크기 구하기
struct stat file_stat;
if (stat(filename, &file_stat) < 0) {
perror("파일 상태 확인 실패");
close(client_socket);
continue;
}
off_t file_size = file_stat.st_size;
// 7. HTTP 응답 헤더 구성
std::stringstream header;
header << "HTTP/1.1 200 OK\r\n";
header << "Content-Type: application/octet-stream\r\n";
header << "Content-Disposition: attachment; filename=\"" << filename << "\"\r\n";
header << "Content-Length: " << file_size << "\r\n";
header << "Connection: close\r\n\r\n";
std::string header_str = header.str();
// 8. 응답 헤더 전송
send(client_socket, header_str.c_str(), header_str.size(), 0);
// 9. 파일 데이터를 청크 단위(예: 4096바이트)로 읽어 전송
const size_t buffer_size = 4096;
char buffer[buffer_size];
while (file) {
file.read(buffer, buffer_size);
std::streamsize bytes_read = file.gcount();
if (bytes_read > 0) {
size_t total_sent = 0;
while (total_sent < static_cast<size_t>(bytes_read)) {
ssize_t sent = send(client_socket, buffer + total_sent, bytes_read - total_sent, 0);
if (sent < 0) {
perror("데이터 전송 오류");
break;
}
total_sent += sent;
}
}
}
std::cout << "파일 전송 완료.\n";
file.close();
close(client_socket);
}
close(server_fd);
return 0;
}
이 컴퓨터에 있는 파일을 다른 컴퓨터로 보내고싶었는데 크기가 커서 메일이나 클라우드에 올리고 받기 시간이 아까웠다.
블루투스도 맘에 안들고 하나는 맥북이고 하나는 우분투라 에어드랍도 안된다.
직접 전송할 수 있게 하면 문제를 해결할 것 같았다.
그래서 나에게 익숙한 C++로 서버를 만들어서 파일을 보내기로 했다.
filename에 파일을 적어두고 빌드해서 실행하고
웹클라이언트로 서버의 8080포트로 접속하면 다운로드 받을 수 있다.