251022

lililllilillll·2025년 10월 22일

개발 일지

목록 보기
332/350

✅ 한 것들


  • 백준
  • 윤성우의 열혈 TCP/IP 소켓 프로그래밍


⚔️ 백준


  • 7579 앱 : 못 풀고 답지만 봤다. 평범한 배낭 문제이고, 발상까지는 했는데, 단어 좀 바꿨다고 무게를 비용으로 헷갈려서 조건 안되는 줄 알아버림.

10942 팰린드롬?

using namespace std;
typedef vector<int> vi;

bool dp[2000][2000];

void B10942::Solution()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m;
	cin >> n;
	vi nums = vi(n);
	for (int i = 0; i < n; i++) cin >> nums[i];

	for (int i = 0; i < n; i++)
	{
		int range = 0;
		while (0 <= i - range && i + range < n)
		{
			if (nums[i - range] == nums[i + range]) 
				dp[i - range][i + range] = true;
			else break;
			range++;
		}
		int offset = 1;
		while (0 <= i - offset + 1 && i + offset < n)
		{
			if (nums[i - offset + 1] == nums[i + offset])
				dp[i - offset + 1][i + offset] = true;
			else break;
			offset++;
		}
	}

	cin >> m;
	while (m--)
	{
		int s, e;
		cin >> s >> e; // -1 한게 인덱스임
		if (dp[s-1][e-1]) cout << 1 << '\n';
		else cout << 0 << '\n';
	}
}

ios::sync_with_stdio(false);cin.tie(nullptr); 이거 안 붙였다고 계속 틀렸었다. 시간 복잡도 잘 계산해놨다면, 그 근거를 의심하지 말고 다른 이유를 찾아라.



📖 윤성우의 열혈 TCP/IP 소켓 프로그래밍


Chapter 15 소켓과 표준 입출력

15-1 표준 입출력 함수의 장점

표준 입출력 함수 장점

  • 이식성이 좋다
  • 버퍼링을 통한 성능 향상
    • 소켓 입출력 버퍼에 더해 추가로 버퍼 제공받고, 그걸로 성능 향상 가능
    • 패킷은 일정한 크기가 있기 때문에, 한 번에 모아서 보내는게 낫다

표준 입출력 함수 단점

  • 양방향 통신 쉽지 않다
  • 상황에 따라서 fflush() 자주 호출해야 한다
    • 읽기 ↔ 쓰기 작업 형태 바꿀 때마다 호출해야 하는데, 성능에도 영향 미친다
  • 파일 디스크립터를 FILE 구조체의 포인터로 변환해야 한다

15-2 표준 입출력 함수 사용하기

int main(void)
{
	FILE *fp;
	int fd=open("data.dat", O_WRONLY|O_CREAT|O_TRUNC);
	if(fd==-1)
	{
		fputs("file open error", stdout);
		return -1;
	}

	fp = fdopen(fd, "w");
	fputs("Network C programming \n", fp);
	fclose(fp);
	return 0;
}

fdopen()을 이용하여 FILE 구조체 포인터로 변환할 수 있다
예제는 open()으로 파일을 생성한 뒤, fdopen()으로 FILE 포인터를 가져온다.

fileno()는 반대다. FILE 포인터를 파일 디스크립터로 바꿔준다.

15-3 소켓 기반에서의 표준 입출력 함수 사용

		readfp=fdopen(clnt_sock, "r");
		writefp=fdopen(clnt_sock, "w");
		while(!feof(readfp))
		{
			fgets(message, BUF_SIZE, readfp);
			fputs(message, writefp);
			fflush(writefp);
		}
		fclose(readfp);
		fclose(writefp);

echo_server.c에서 write()를 사용하던 부분을
문자열 기반의 fgets, fputs로 변경

	readfp=fdopen(sock, "r");
	writefp=fdopen(sock, "w");
	while(1)
	{
		fputs("Input message(Q to quit): ", stdout);
		fgets(message, BUF_SIZE, stdin);

		if(!strcmp(message, "q\n") || !strcmp(message,"Q\n"))
			break;

		fputs(message,writefp);
		fflush(writefp);
		fgets(message, BUF_SIZE, readfp);
		printf("Message from server : %s", message);
	}

echo_client.c를 문자열 기반 fgets, fputs로 변경
원래는 데이터 마지막에 0 삽입해서 수신 데이터를 문자열로 구성해야 했지만,
위에선 표준 입출력 함수를 사용하기 때문에 생략됐다.

보다시피 적용에 따른 부가적인 코드 발생 때문에 생각만큼 즐겨쓰진 않는다.

Chapter 16 입출력 스트림의 분리에 대한 나머지 이야기

16-1 입력 스트림과 출력 스트림의 분리

half close : 연결 종료해도 받을 데이터 있을 수 있으니 일부만 닫는거
Chapter 10에선 shutdown()으로 half close 구현했다.
출력모드 FILE 포인터로 fclose() 호출하면? half close가 아니라 입출력 다 닫혀버린다.

16-2 파일 디스크립터의 복사와 Half-close

FILE 포인터

  • 파일 디스크립터 기반 생성됨
  • fclose() 해도 연결된 파일 디스크립터 종료, 이어 소켓도 종료
  • 파일 디스크립터 복사해서 FILE 포인터 따로 만들어야 함
  • 따로 만든 FILE 포인터 닫아도 Half-close는 아님
    • 상대 호스트로 EOF도 전송 안됨
    • 파일 디스크립터를 쓰면 출력도 여전히 가능

dup() : 파일 디스크립터 복사. 새 정수값 할당됨.
dup2() : 복사될 정수 값도 지정

writefp 만들 때 클라 소켓의 dup()을 인자로 주고,
shutdown(fileno(writefp), SHUT_WR) 호출하면 Half-close 진행됨.



profile
너 정말 **핵심**을 찔렀어

0개의 댓글