๐๐ป ๊ธฐ๋ณธ์ ์ธ ์์ผ์ ๋ํ ์ค๋ช
์
๋๋ค.
This is an explanation of basic sockets.
๐๐ป Echo Server๋ ํด๋ผ์ด์ธํธ์์ ๋ณด๋ธ ๋ฉ์ธ์ง๋ฅผ ์๋ฒ๊ฐ ๋ค์ ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ด๋ ๊ฐ๋จํ ์ฝ๋์
๋๋ค.
Echo Server is simple code that sends a message sent from a client back to the client.
๐๐ป Thread Server๋ ์์ฃผ ๊ธฐ๋ณธ์ ์ธ ์ฑํ
์๋ฒ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
Thread Server has a very basic chat server structure.
๐๐ป Echo Server
โ๏ธ Server.cpp
#include <iostream>
#include <sys/socket.h> // ์์ผ API / Socket API
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
int main() {
// ์์ผ ์์ฑ,0์ ํ๋กํ ์ฝ ์๋ ์ ํ
// // Create socket, 0 for automatic protocol selection
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in address;
address.sin_family = AF_INET; // IPv4
address.sin_addr.s_addr = INADDR_ANY; // ๋ชจ๋ IP ํ์ฉ / Allow all IPs
address.sin_port = htons(5080); // ํฌํธ 8080 / Port 8080
bind(server_fd, (struct sockaddr*)&address, sizeof(address)); // ์ฃผ์ ๋ฐ์ธ๋ฉ / Address Binding
listen(server_fd, 3); // ์ ์ ๋๊ธฐ / Waiting for connection
std::cout << "listening..." << std::endl;
int new_socket = accept(server_fd, nullptr, nullptr); // ์ฐ๊ฒฐ ์๋ฝ / Accept Connection
char buffer[1024] = {0};
read(new_socket, buffer, 1024); // ๋ฐ์ดํฐ ์์ / Receive Data
std::cout << "์์ ๋ ๋ฉ์์ง / Received Message: " << buffer << std::endl;
const char* hello = "Hello from server";
send(new_socket, hello, strlen(hello), 0); // ์๋ต ์ ์ก / Send Response
close(new_socket);
close(server_fd);
return 0;
}
โ๏ธ Client.cpp
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
int main() {
int sock = socket(AF_INET, SOCK_STREAM, 0); // ์์ผ ์์ฑ / create socket
sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5080);
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); // ์๋ฒ IP ์ค์ / Server IP settings
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); // ์๋ฒ ์ ์ / server connection
const char* message = "Hello from client";
send(sock, message, strlen(message), 0); // ๋ฉ์ธ์ง ์ ์ก / Send Message
char buffer[1024] = {0};
read(sock, buffer, 1024); // ์๋ฒ ์๋ต ์์ / Receive Server Response
std::cout << "์๋ฒ ์๋ต / Server Response: " << buffer << std::endl;
close(sock); // ์์ผ ์ข
๋ฃ / Close Socket
return 0;
}
โ๏ธ ์ปดํ์ผ / Compiling
g++ Server.cpp -o server -std=c++17
g++ Client.cpp -o client -std=c++17
โ๏ธ ์คํ / Run
./server
./client
โ๏ธ ๊ฒฐ๊ณผ / Result
# server
MacBookAir echo % ./server
listening...
์์ ๋ ๋ฉ์์ง / Received Message: Hello from client
# client
MacBookAir echo % ./client
์๋ฒ ์๋ต / Server Response: Hello from server
๐๐ป ThreadServer
โ๏ธthreadServer.cpp
#include <iostream>
#include <thread> // ์ค๋ ๋ ํค๋ / thread header
#include <vector>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
// ํด๋ผ์ด์ธํธ์ ํต์ ํ๊ธฐ ์ํ ํจ์
// A function to communicate with the client
void handle_client(int client_socket) {
char buffer[1024];
while (true) {
// ๋ฒํผ๋ฅผ ๋ชจ๋ 0์ผ๋ก ์ด๊ธฐํํด์ ๊ธฐ์กด ์ฐ๋ ๊ธฐ ๊ฐ ์ง์ฐ๊ธฐ
// Initialize buffer to all 0s to clear existing garbage values
memset(buffer, 0, 1024);
ssize_t valread = read(client_socket, buffer, 1024);
if (valread <= 0) {
std::cout << "ํด๋ผ์ด์ธํธ ์ ์ ์ข
๋ฃ / Client connection terminated " << std::endl;
break;
}
std::cout << "์์ ๋ ๋ฉ์์ง / Received message: " << buffer << std::endl;
send(client_socket, buffer, valread, 0); // send
}
close(client_socket);
}
int main() {
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
// ํฌํธ๊ฐ ์ด๋ฏธ ์ฌ์ฉ ์ค์ด์ด๋ ์ฆ์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๊ฒ ์ค์
// Configure port to be immediately reusable even if it is already in use
int opt = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(5080);
if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
perror("Bind failed"); // ์๋ฌ ๋ด์ฉ ์ถ๋ ฅ / Error details output
return 1;
}
if (listen(server_fd, 5) < 0) {
perror("Listen failed");
return 1;
}
std::cout << "์๋ฒ ์ ์ ์์, ์ ์ ๋๊ธฐ ์ค / Server started normally, waiting for connection ..." << std::endl;
while (true) {
int client_sock = accept(server_fd, nullptr, nullptr);
if (client_sock < 0) {
perror("Accept failed");
continue;
}
std::cout << "์ ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ๋จ / New Client Connected: " << client_sock << ")" << std::endl;
std::thread(handle_client, client_sock).detach();
}
return 0;
}
โ๏ธClient.cpp
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
int main() {
int sock = socket(AF_INET, SOCK_STREAM, 0); // ์์ผ ์์ฑ / create socket
sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5080);
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); // ์๋ฒ IP ์ค์ / Set Server IP
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); // ์๋ฒ ์ ์ / Connect to Server
// const char* message = "Hello from client";
// send(sock, message, strlen(message), 0); // ๋ฉ์์ง ์ ์ก
// char buffer[1024] = {0};
// read(sock, buffer, 1024); // ์๋ฒ ์๋ต ์์
// std::cout << "์๋ฒ ์๋ต: " << buffer << std::endl;
while (true) {
std::string msg;
std::cout << "๋ณด๋ผ ๋ฉ์์ง (์ข
๋ฃ๋ quit): ";
std::getline(std::cin, msg); // ํค๋ณด๋ ์
๋ ฅ ๋ฐ๊ธฐ / Receiving keyboard input
// quit๊ฐ ์
๋ ฅ๋๋ฉด... / When quit is entered...
if (msg == "quit") break;
send(sock, msg.c_str(), msg.length(), 0); // ๋ฉ์ธ์ง๋ฅผ ์๋ฒ๋ก ์ ์ก / Send message to server
char buffer[1024] = {0};
int valread = read(sock, buffer, 1024); // ์๋ฒ ์๋ต ๋๊ธฐ / Waiting for server response
if (valread <= 0) {
std::cout << "์๋ฒ์์ ์ฐ๊ฒฐ์ด ๋๊ฒผ์ต๋๋ค. / Server connection closed." << std::endl;
break;
}
std::cout << "์๋ฒ ์๋ต / Server response:: " << buffer << std::endl;
}
close(sock); // ์์ผ ์ข
๋ฃ / Socket close
return 0;
}
โ๏ธ ์ปดํ์ผ / Compiling
g++ threadServer.cpp -o server -std=c++17 -pthread
g++ Client.cpp -o client -std=c++17
โ๏ธ ์คํ / Run
./server
./clinet
โ๏ธ๊ฒฐ๊ณผ / Result
# server
MacBookAir thread % ./server
์๋ฒ ์ ์ ์์, ์ ์ ๋๊ธฐ ์ค / Server started normally, waiting for connection ...
์ ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ๋จ / New Client Connected: 4)
์์ ๋ ๋ฉ์์ง / Received message: hello
์์ ๋ ๋ฉ์์ง / Received message: ์๋
ํ์ธ์
์์ ๋ ๋ฉ์์ง / Received message: 8
ํด๋ผ์ด์ธํธ ์ ์ ์ข
๋ฃ / Client connection terminated
#client
MacBookAir thread % ./client
๋ณด๋ผ ๋ฉ์์ง / Message to send (์ข
๋ฃ/Quit: quit): hello
์๋ฒ ์๋ต / Server response:: hello
๋ณด๋ผ ๋ฉ์์ง / Message to send (์ข
๋ฃ/Quit: quit): ์๋
ํ์ธ์
์๋ฒ ์๋ต / Server response:: ์๋
ํ์ธ์
๋ณด๋ผ ๋ฉ์์ง / Message to send (์ข
๋ฃ/Quit: quit): 8
์๋ฒ ์๋ต / Server response:: 8
๋ณด๋ผ ๋ฉ์์ง / Message to send (์ข
๋ฃ/Quit: quit): quit
MacBookAir thread %