-
[열혈 TCP/IP 소켓 프로그래밍] Chapter2. 내용 확인문제Study/Network 2022. 9. 19. 19:50
01. 프로토콜이 무엇인가?
- 프로토콜이란, 데이터의 전송 방식을 결정하는 규약이다.
- 두 컴퓨터 간 프로토콜을 정의해야 데이터 전송 방식을 서로 알고 해석할 수 있다.
02. 연결지향 소켓 TCP의 전송 특성 3가지
- 데이터의 손실이 없음이 보장된다.
- 데이터의 경계가 없다
- 데이터의 전송 순서가 보장된다.
03. 비연결지향 소켓 UDP의 전송 특성
- 데이터의 손실이 있을 수 있다.
- 빠른 전송을 목표로 한다.
- 한 번의 전송에 데이터의 크기가 제한된다.
- 연결이라는 개념이 존재하지 않는다.
04. 유형별 적합한 타입의 소켓은?
- 실시간 스트리밍 : UDP 소켓. 빠른 전송이 목표가 되어야 하고, 데이터가 손실되더라도 최신의 데이터를 계속 받는 것이 더 중요하다.
- 텍스트 파일 전송 : TCP 소켓. 순서가 무조건 보장되어야 하고 데이터의 손실이 없어야 한다.
- 인터넷 뱅킹 : 데이터의 손실이 절대 있어서는 안 된다.
05. 데이터의 경계가 존재하지 않는 소켓은? 그리고 이러한 소켓을 통해 데이터를 수신할 때 주의점
- 데이터의 경계가 존재하지 않는 소켓은 TCP 소켓이다.
- 수신할 때 주의할 점은, 소켓 내부의 버퍼에 데이터가 저장되고, read 함수 호출을 통해 버퍼에 있는 데이터를 비우는 방식이기 때문에 버퍼가 가득 차게 된다면 더 이상 데이터를 수신할 수 없다.
- 데이터가 손실되지는 않지만 데이터를 더 이상 받을 수 없기 때문에 주의해야 한다.
06. 서버에서 데이터를 쪼개서 보내보기
서버 코드
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") void ErrorHandling(char* Message); int main(int argc, char* argv[]) { WSADATA wsaData; SOCKET hServerSock, hClntSock; SOCKADDR_IN servAddr, clntAddr; int szClntAddr; char message[] = "Hello World!"; if (argc != 2) { printf("Usage %s <port>\n", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { ErrorHandling("WSAStartUp() error"); } hServerSock = socket(PF_INET, SOCK_STREAM, 0); if (hServerSock == INVALID_SOCKET) { ErrorHandling("socket() error"); } memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(atoi(argv[1])); if (bind(hServerSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) { ErrorHandling("bind() error"); } if (listen(hServerSock, 5) == SOCKET_ERROR) { ErrorHandling("listen() error"); } szClntAddr = sizeof(clntAddr); hClntSock = accept(hServerSock, (SOCKADDR*)&clntAddr, &szClntAddr); if (hClntSock == INVALID_SOCKET) { ErrorHandling("accept() error"); } int len = strlen(message); for (int i = 0; i < len; ++i) { send(hClntSock, &message[i], sizeof(char), 0); } closesocket(hClntSock); closesocket(hServerSock); WSACleanup(); } void ErrorHandling(char* Message) { fputs(Message, stderr); fputc('\n', stderr); exit(1); }
클라이언트 코드
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") void ErrorHandling(char* Message); int main(int argc, char* argv[]) { WSADATA wsaData; SOCKET hSocket; SOCKADDR_IN servAddr; char message[30]; if (argc != 3) { printf("Usage : %s <IP> <port>\n", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { ErrorHandling("WSAStartup() error"); } hSocket = socket(PF_INET, SOCK_STREAM, 0); if (hSocket == INVALID_SOCKET) { ErrorHandling("socket() error"); } memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr(argv[1]); servAddr.sin_port = htons(atoi(argv[2])); if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) { ErrorHandling("connect() error"); } // busy - waiting for (int i = 0; i < 3000; ++i) { printf("Wait Time : %d\n", i); } recv(hSocket, message, 12, 0); message[12] = '\0'; printf("Message From Server : %s", message); closesocket(hSocket); WSACleanup(); return 0; } void ErrorHandling(char* Message) { fputs(Message, stderr); fputc('\n', stderr); exit(1); }
'Study > Network' 카테고리의 다른 글
[열혈 TCP/IP 소켓 프로그래밍] Chapter4. 내용 확인문제 (0) 2022.10.08 [열혈 TCP/IP 소켓 프로그래밍] Chapter3. 내용 확인문제 (1) 2022.09.22 [열혈 TCP/IP 소켓 프로그래밍] Chapter1. 내용 확인문제 (0) 2022.09.15