- 인터넷 프로토콜 기반 소켓에서 데이터 전송방법에 따라 TCP 소켓과 UDP 소켓으로 나뉘는데, TCP 소켓은 연결을 지향하기 때문에 '스트림 기반 소켓'이라고도 한다.
- TCP와 UPD의 계층은 전송(Transport) 계층이다.
- TCP 계층은 IP 계층에서 알려준 경로정보를 바탕으로 데이터를 송수신하는데, IP 계층의 경우 하나의 데이터 패킷이 전송되는 과정에만 중심을 두고 설계되었기 때문에 데이터의 주고받음을 확인하고 분실된 데이터에 대한 재전송을 보장하여 데이터 전송에 신뢰성을 부여한 프로토콜이다.
TCP 통신에서 신뢰성있는 데이터 송수신을 위해 두 장치 간에 동기를 맞추는 과정이 필요하다.
통신을 시작할 때 -> 3 way handshake
통신을 종료할 때 -> 4 way handshake
TCP 서버에서서의 기본적인 함수 호출 순서
socket() -> bind() -> listen() -> accept() -> read()/write() -> close()
소켓 생성-> 소켓 주소 할당 -> 연결 요청 대기상태 -> 연결 허용 -> 데이터 송수신 -> 연결 종료
/* TCP 서버 예제 코드 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
ing main(int argc, char *argv[])
{
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in clng_addr;
soclen_t clnt_addr_size;
char message[] = "Hellow World!";
if(argc != 2)
{
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv_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 = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
error_handling("bind() error");
if(listen(serv_sock, 5) == -1) error_handling("listen() error");
clnt_addr_size = sizeof(clnt_addr);
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
if(clnt_sock == -1) error_handling("accept() error");
write(clnt_sock, message, sizeof(message));
close(clnt_sock);
close(serv_sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
/* TCP 클라이언트 예제 코드 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
int main(argc, char *argv[])
{
int sock;
struct sockaddr_in serv_addr;
char message[30];
int str_len;
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() 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!");
str_len = read(sock, message, sizeof(message) - 1);
if(str_len == -1) error_handling("read() error!");
printf("Message from server : %s\n", message);
close(sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exec(1);
}
코드 출처 및 내용 참고 : 윤성우의 열혈 TCP/IP 소켓 프로그래밍, 윤성우, orange media
'Network' 카테고리의 다른 글
| UDP (User Datagram Protocol) (0) | 2020.05.16 |
|---|