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);
결과출력
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 |