그럴듯한 개발 블로그
article thumbnail
Published 2023. 10. 16. 18:47
간단 echo server 구현 (C++) <language>/c++
반응형

socket관련 시스템콜 함수들을 사용해 보았다.

#include <iostream>
#include <sys/socket.h> // server.cpp
#include <netinet/in.h>
#include <unistd.h>

#define PORT 8080

int main() {
	int sock, new_sock;
	struct sockaddr_in addrStruct;

	// 소켓 만들기
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
		std::cerr << "Socket failed" << std::endl;
		exit(EXIT_FAILURE);
	}

	addrStruct.sin_family = AF_INET;
	addrStruct.sin_addr.s_addr = INADDR_ANY; // 모든 ip접근허가
	addrStruct.sin_port = htons(PORT); // 엔디안 맞춰줌

	// 소켓에 현재 IP, port 등록
	if (bind(sock, reinterpret_cast<struct sockaddr*>(&addrStruct), sizeof(addrStruct)) < 0) {
		std::cerr << "Bind failed" << std::endl;
		exit(EXIT_FAILURE);
	}

	// 연결 요청 대기 상태로 바꿔줌
	if (listen(sock, 3) < 0) {
		std::cerr << "Listen failed" << std::endl;
		exit(EXIT_FAILURE);
	}
	while (true) {
		// 클라이언트 연결 오면 새로운 소켓 만들어서 반환해줌 연결 오기전까지 block되어있음
		socklen_t sockLen = sizeof(addrStruct);
		if ((new_sock = accept(sock, reinterpret_cast<struct sockaddr*>(&addrStruct), &sockLen)) < 0) {
			std::cerr << "accept failed" << std::endl;
			exit(EXIT_FAILURE);
		}
		char buffer[1024];
		ssize_t readSize = read(new_sock, buffer, 1024);
		std::cout << "accept!!" << std::endl;
		send(new_sock, buffer, readSize, 0);
	}
}
#include <iostream> // client.cpp
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 8080

int main() {

	int sock = 0;
	struct sockaddr_in addrStruct;

	char message[] = "my name is donghyun";

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { // IPv4, TCP
		std::cerr << "Socket creation error" << std::endl;
		exit(EXIT_FAILURE);
	}

	addrStruct.sin_family = AF_INET; // IPv4프로토콜 사용
	addrStruct.sin_addr.s_addr = inet_addr("127.0.0.1"); // 목적지 ip주소
	addrStruct.sin_port = htons(PORT); // 엔디안 맞춰줌

	if(connect(sock, reinterpret_cast<struct sockaddr*>(&addrStruct), sizeof(addrStruct)) < 0) {
		// 소켓 연결
		std::cerr << "Connection Failed" << std::endl;
		exit(EXIT_FAILURE);
	}

	send(sock, message, strlen(message) + 1, SOCK_STREAM); //널문자까지 보내야함
	char buffer[1024];
	ssize_t readSize = read(sock, buffer, sizeof(buffer));
	write(1, buffer, readSize);
}


오랜만에 strlen쓰다가 마지막 널문자 빼고 send해서 message 하나 짤리는 불상사가 발생했다;;
또 accept함수에서 size를 굳이 포인터로 바꿔서 받는데 이런 경우는 또 처음 봐서 찾아보니 IPv4, IPv6같이 동적으로 변할 수 있는 네트워크 주소의 길이를 맞춰서 바꿔주기 위함이였다. 신기방기

반응형

'<language> > c++' 카테고리의 다른 글

c++ class 상속, 가상함수 테이블, 추상클래스  (0) 2023.08.07
c++ 레퍼런스(참조자)  (8) 2023.07.06
c++ 동적할당  (0) 2023.07.06
cpp 파일 컨트롤(ifstream ofstream)  (0) 2023.07.05
cpp split  (0) 2023.05.29
profile

그럴듯한 개발 블로그

@donghyk2

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!