본문 바로가기
일상,취미

다시 시작하는 TIL 15일차

by 진득한진드기 2024. 6. 27.

오늘 한일 

 

오늘은 이렇다할 특정 문제를 해결하진 못했다.

 

window 프로그래밍에서 내가 원하는 이벤트가 일어나면 그때 http 요청을 해야되는데 https 요청을 하려고 하니 SSL 라이브러리가 먹지를 않아서 진짜 화가 머리 끝까지 났다.

 

해당 DLL 이 왜 안되는지는 아직 까지 모른다.

 

그래서 진짜 하루종일 해보려고 하다가 결국 터널링해서 https로 해보려고 까지 했다.

 

내가 교본 코드에도 나와있는 방식이라 아무생각 없이 따라해서 해결하려 했는데 선임 말로는 비추천하는 방식이다.

 

먼저 프록시로 사용할 프록시로 사용할 TCP 소켓을 생성한다.

 

이후 HTTP CONNECT 메서드를 사용하여 클라이언트가 프록시 서버를 통해 SSL/TLS 연결을 설정할 수 있게 해준다.

 

이 방식을 통해 클라이언트와 최종 서버 간의 연결을 프록시가 단순히 전달하는 역할을 하게 한다.

 

프록시 서버는 클라이언트로부터 받은 요청을 기반으로 목적지 서버와 TCP 연결을 설정한다.

 

연결이 설정되면 프록시 서버는 클라이언트에게 200 Connection Established라는 응답을 보내는데 이후 클라이언트와 목적지 서버 간의 통신은 암호화된 상태로 프록시 서버를 통해 전달된다.

 

SSL/TLS 핸드셰이크를 통해서 클라이언트와 목적지 서버는 SSL/TLS 핸드셰이크를 수행하여 보안 연결이 설정된다.

 

이 과정을 통해서 구현하면 Https 요청을 터널링 해서 사용하게 된다. 

 

그냥 회사 코드 보고 하려고 했는데 해당 방식이 터널링하는 것이라 굳이 라는 느낌이 들긴한다.

 

내일 차라리 라이브러리 자체를 다시 받아봐야겠다.

 

퇴근 후 공부


서버에서 accpet 함수를 호출하면 계속해서 연결 요청 대기 큐에 있는 클라이언트들의 연결요청을 수락할 수 있다. 그러나 동시에 둘 이상의 클라이언트에게 서비스를 제공할 수 있는 모델은 아니다.

 

애초에 TCP 자체가 1대 1 모델이기 때문이다.


이런 모델은 바로 연결 요청만 여러개 다 수락하는 모델인것이다.


TCP의 데이터 송수신에는 경계가 존재하지 않는다.


TCP에는 데이터의 경계가 존재하지 않기 때문에 서버가 전송한 문자열의 일부만 읽혀질 수 도 있다.


예시로 서버 와 클라이언트가 있다고 해보자.


클라이언트가 write함수를 호출로 굉장히 긴 문자열을 보냈다고 해보자

 

그 긴 문자열이 서버에 오게 되는데 서버가 절반만 읽고 절반만 read해서 다시 클라이언트에게 전송해버릴 수 도있다.


이렇게 나머지 절반만 읽고 read하게 되면 클라이언트는 절반만 받게된다.

 

 

데이터의 경계를 생각하지 않은 client 소켓 프로그램

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>


#define BUF_SIZE 1024

void error_handling(char *message){
	printf("%s \n",message);
}

int main(int argc,char *argv[]) {
	int sock;
	char message[BUF_SIZE];
	int str_len;

	struct sockaddr_in serv_addr;

	if(argc != 3) {
		printf("Usage : %s <port>\n",argv[0]);
		exit(1);
	}

	sock = socket(PF_INET, SOCK_STREAM, 0);
	if(sock == -1)
		error_handling("socket() ERROR");

	memset(&serv_addr,0,sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
	serv_addr.sin_port = htons(atoi(argv[2]));

	if(connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
		error_handling("connect() ERROR");

	else
		puts("Connected.........");
	while(1)
	{
		fputs("input message(0 to quit)",stdout);
		fgets(message,BUF_SIZE,stdin);

		if(!strcmp(message,"q\n") || !strcmp(message, "Q\n"))
			break;
		write(sock, message, strlen(message));
		str_len = read(sock, message, BUF_SIZE-1);
		message[str_len] = 0;
		printf("Message from server : %s",message);
	}
	close(sock);
	return 0;
}

 


즉 해결해야될 문제는 "내가 보낸 바이트 크기와 맞는지 검사를 해야한다." 라는 것이다.

 

즉 그 바이트 크기가 맞을 때 까지 read함수를 반복 호출해야하는 구조가 옮다.

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define BUF_SIZE 1024

void error_handling(char *message){
	printf("%s \n",message);
}


int main(int argc,char *argv[]){
	int sock;
	char message[BUF_SIZE] ;
	int str_len,recv_len, recv_cnt;

	struct sockaddr_in serv_adr;

	if(argc != 3){
		printf("Usage : %s <IP> <PORT>\n",argv[0]);
		exit(1);
	}

	sock = socket(PF_INET,SOCK_STREAM,0);
	if(sock == -1)
		error_handling("SOCKET() ERORR");

	memset(&serv_adr,0,sizeof(serv_adr));
	serv_adr.sin_family = AF_INET;
	serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
	serv_adr.sin_port = htons(atoi(argv[2]));

	if(connect(sock,(struct sockaddr *) &serv_adr,sizeof(serv_adr)) == -1)
		error_handling("Connect() ERROR");
	else
		puts("Connected.....");

	while(1) 
	{
		fputs("Input Message(Q to quit): ",stdout);
		fgets(message, BUF_SIZE,stdin);
		if(!strcmp(message , "q\n") || !strcmp(message,"Q\n"))
			break;

		str_len = write(sock,message, strlen(message));
		recv_len = 0;
        // 길이를 읽어오고 해당 길이 만큼 read하여 데이터 경계를 맞춘다.
		while(recv_len < str_len)
		{
			recv_cnt = read(sock , &message[recv_len], BUF_SIZE-1);
			if(recv_cnt == -1)
				error_handling("Read() ERROR");
			recv_len += recv_cnt;
		}
		message[recv_len] = 0;
		printf("Message from server : %s ", message);
	}
	close(sock);

	return 0;
}


해당 구조가 TCP구조에 맞는 구조이다.

'일상,취미' 카테고리의 다른 글

다시 시작하는 TIL 17일차  (0) 2024.06.29
다시 시작하는 TIL 16일차  (0) 2024.06.28
다시 시작하는 TIL 14일차  (0) 2024.06.26
다시 시작하는 TIL 13일차  (0) 2024.06.24
다시 시작하는 TIL 12일차  (0) 2024.06.22