공부

20200902 공부

글로벌디노 2020. 9. 2. 13:44

1. 데이터 전송하기 2

1) 가변 길이 데이터 전송 연습

2) 고정 길이 + 가변 길이 데이터 전송 연습

3) 데이터 전송 후 종료 연습

 

 

1. 데이터 전송하기 2

 

1) 가변 길이 데이터 전송 연습

 

클라이언트 코드 수정

// 가변 길이 데이터 전송
// EOR = '\n'
const int bufSize = 50;
char buf[bufSize];

const char* testData[] =
{
	"안녕하세요",
	"반가워요",
	"오늘따라 할 이야기가 많을 것 같네요",
	"저도 그렇네요"
};

for (int i = 0; i < 4; i++)
{
	int len = strlen(testData[i]);
	strcpy_s(buf, bufSize, testData[i]);
	buf[len++] = '\n';

	ret = send(sock, buf, len, 0);
	if (ret == SOCKET_ERROR) {...}
}

 

서버 코드 수정

const int bufSize = 512;
char buf[bufSize + 1];

// 데이터 수신
while (1)
{
	ret = recvline(clientSock, buf, bufSize + 1);
	
        // 에러처리..

	printf_s("recv size : %d\n", ret);
	printf_s("%s", buf);
}

/////////////////////////////////////////////////

int recvline(SOCKET socket, char* buf, int maxLen)
{
	int n, nbytes;
	char c, *ptr = buf;

	for (n = 1; n < maxLen; n++)
	{
		nbytes = _recv_ahead(socket, &c);

		if (nbytes == 1)
		{
			*ptr++ = c;
			if (c == '\n')
				break;
		}
		else if (nbytes == 0)
		{
			*ptr = 0;
			return n - 1;
		}
		else
			return SOCKET_ERROR;
	}

	*ptr = 0;
	return n;
}

/////////////////////////////////////////////////

int _recv_ahead(SOCKET socket, char* p)
{
	static int nbytes = 0;
	static char buf[1024];
	static char* ptr;

	if (nbytes == 0 || nbytes == SOCKET_ERROR)
	{
		nbytes = recv(socket, buf, sizeof(buf), 0);
		
		if (nbytes == SOCKET_ERROR || nbytes == 0)
			return nbytes;

		ptr = buf;
	}

	--nbytes;
	*p = *ptr++;
	return 1;
}

 

서버코드를 정리하자면...

... 내가 알아볼 수 있으면 됐지 뭐 ... ㅎㅎ

 

결과출력

 

 

 

 

2) 고정 길이 + 가변 길이 데이터 전송 연습

 

송신측에서 가변 길이 데이터의 크기를 곧바로 계산할 수 있다면 고정길이 + 가변길이전송 이 효과적이다.

수신측에서는 '1. 고정길이 데이터 수신, 2. 가변길이 데이터 수신' 두 번의 데이터 수신으로 가변 길이 데이터의 경계를 구분해 읽을 수 있다.

 

클라이언트 코드 수정

// 고정 길이 + 가변 길이 데이터 전송
for (int i = 0; i < 4; i++)
{
	int len = strlen(testData[i]);
	// NULL 문자 제외하고 복사
	memcpy_s(buf, bufSize, testData[i], len);

	// 데이터 송신 (고정길이)
	// 다음에 보낼 가변 데이터 크기 전달 (4byte 정수)
	ret = send(sock, (char*)&len, sizeof(int), 0);
	
	// 데이터 송신 (가변길이)
	ret = send(sock, buf, len, 0);
}

 

서버 코드 수정

// 데이터 수신 (고정길이)
int len;
ret = recvn(clientSock, (char*)&len, sizeof(int), 0);

// 출력
printf_s("[recv:%3d] %d\n", ret, len);


// 데이터 수신 (가변길이)
ret = recvn(clientSock, buf, len, 0);

//출력
buf[ret] = '\0';
printf_s("[recv:%3d] %s\n", ret, buf);

recvn 함수 코드는 여기있음

 

결과출력

 

 

 

3) 데이터 전송 후 종료 연습

 

일종의 가변 길이 데이터 전송 방식이다.

EOR로 특별한 데이터 패턴을 사용하는 대신 연결 종료를 사용한다.

 

클라이언트 코드 수정

for (int i = 0; i < 4; i++)
{
	// 소켓생성
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
        // 연결
	int ret = connect(sock, (SOCKADDR*)&servAddr, sizeof(servAddr));
	
        // NULL 문자 제외하고 복사
	int len = strlen(testData[i]);
	memcpy_s(buf, bufSize, testData[i], len);

	// 데이터 송신
	ret = send(sock, buf, len, 0);

	closesocket(sock);
}

 

서버 코드 수정

while (1)
{
	// 데이터 수신
	ret = recvn(clientSock, buf, bufSize, 0);

	if (ret == SOCKET_ERROR) break;
	// 소켓연결이 끊기면 데이터 수신 종료
	else if (ret == 0)
	{
		printf_s("connection close\n");
		break;
	}

	buf[ret] = '\0';
	printf_s("[recv:%3d] %s\n", ret, buf);
}

closesocket(clientSock);

 

결과출력

 

'공부' 카테고리의 다른 글

20200904 공부  (0) 2020.09.04
20200903 공부  (0) 2020.09.03
20200901 공부  (0) 2020.09.02
20200831 공부  (0) 2020.09.01
24bit BMP 파일 읽어서 윈도우 출력  (0) 2020.08.25