프로그래밍 노트

[winsock 초보 프로그래밍] 05 TCP 써보기 본문

통신관련

[winsock 초보 프로그래밍] 05 TCP 써보기

띠리 2007. 4. 16. 20:09
윈속을 써서TCP에 의한 통신을 해보자.

----------------------------------------------------------------------

TCP는 무엇일까?

인터넷으로 통신할 때 90% 이상은 TCP에 의해 통신하고 있다고 해도 과언은 아니다. 인터넷에서 통신을 행하는 프로그램을 짤때 거의다가  TCP에 의한 것일 것 같다.

인터넷은 신뢰성이 없는 통신망이다. 신뢰성이 없는 인터넷은 통신중에 패킷을 잃어버리거나 비트에러, 패킷의 순서가 바뀌는 등 여러가지 에러가 발생할 가능성이 있다. TCP는 그와 같은 통신경로의 장애를 커버해준다. 구체적으로는 패킷 로스가 발생하면 다시 보내주거나 패킷의 순서가 바뀌면 바른 순서로 고쳐준다.

TCP에 의한 통신은 서버와 클라이언트의 양자같에 이루어진다. 서버는 통신 요구를 계속 기다린다. TCP에 의한 통신은 클라이언트가 서버에 대하여 접속 요구를 보내는 것으로 시작된다. 서버가 접속 요구를 받아 들이면 클라이언트와 서버간에 가상적인 접속(Virtual Curcit)이 생겨난다.

프로그램을 짤때, 이 소켓이 이 Virtual curcit을 나타낸다. 사용자가 소켓에 대해서 쓰기를 하면 반대쪽 소켓에 이 데이터가 그대로 전송되어진다.
그렇기 때문에 소켓은 양쪽의 사용자가 패킷의 분실에 대한 것을 걱정하지 않고 소켓에 대하여 쓰고 읽기를 하려 통신을 할 수 있다.

TCP에 대해 더 궁금하면 책을 사보는 것이 좋을 것같다.
TCP/IP에 대한 설명만으로도 책한권이 되는 것을 여기에 다 쓸 수 는 없으니까...
(나는 제대로 알지도 못하고...)


----------------------------------------------------------------------

TCP프로그래밍

TCP에 의한 통신을 하는 프로그램일 짤때는 서버와 클라이언트로 나누어 진다.
서버와 클라이언트의 프로그램을 작성하는 순서의 개요를 간단하게 적어본다.


서버

서버는 클라이언트로부터 접속 요구를 기다린다.
접속요구를 기다리려면 어느 정도의 설정이 필요하다.
기다리는 쪽에 필요한 설정은 TCP의 포트를 설정해야된다.

누군가와 만나기로 약속을 했을 경우, 어디서 만날 것인가를 정해야한다.
예를들어 친구와 우리집에서 만나기로 했다.
우리집에 1, 2, 3, 4, 5라고 이름 붙은 문이 다섯개 있다고 했을때
나는 친구에게 5번 문을 열어 놓고 친구를 기다린다.
하지만 친구가 5번 문으로 들어오지 않고 다른 문으로 들어오려하면 친구는 집에 들어 올수가 없다.

기다리고 있는 쪽에서 문을 열어놓아야지만 친구와 만날 수 있는 것처럼 TCP통신에 있어서도 서버쪽에서는 TCP포트를 열고 기다려야된다.
한번 접속이 되면 서버와 클라이언트로 통신하는데는 틀릴 것이 없다.

 - 소켓을 만든다.
 - 접속을 기다릴 포트 번호를 설정한다.
 - 소켓의 이름을 붙인다.(bind한다.)
 - 접속을 기다린다.
 - 클라이언트로 부터 접속을 받는다.
 - 통신을 한다.


클라이언트

클라이언트는 특정 IP어드레스와 TCP포트 번호로 접속을 기다리고 있는 서버에 대해 접속을 요구한다. 접속이 되면 통신을 시작할 수 있다.
서버의 경우 TCP포트를 열고 기다리면 된다. 클라이언트 같은 경우는 TCP포트는 물론 설정하지만 그 외에도 IP어드레스를 설정해야된다.

이것을 쉽게 이해하고자하면 전화를 생각하면 편한다.
전화를 걸때 전화를 거는 사람은 전화번호를 입력하고 전화를 걸어야된지만 전화를 받는 사람은 자신의 전화번호를 입력하지않아도 전화를 받을 수 있다.

전화처럼 클라이언트가 서버에 접속하기 위해서는  IP어드레스가 필요하다.
한번 접속이 되면 서버와 클라이언트로 통신하는데는 틀릴 것이 없다.
 
 - 소켓을 만든다.
 - 접속 상대의 IP어드레스와 TCP포트를 설정한다.
 - 접속한다.
 - 통신을 한다.

----------------------------------------------------------------------

초간단 TCP 서버

윈속을 사용한 초간단 서버. 코드 간략화를 위해 에러처리는 뺐다.
실제 프로그래밍을 할때는 에러 처리를 넣어야된다.

======================================================================

#include <winsock2.h>


int main()

{

    WSADATA wsaData;

    SOCKET    sockSvr;

    SOCKET    sockSS;

    int        nlen;

    struct sockaddr_in    addrSockSvr;

    struct sockaddr_in    addrSockclt;


    // 윈속 초기화

    WSAStartup(MAKEWORD(2, 0), &wsaData);


    // 소켓 만들기

    sockSvr = socket(AF_INET, SOCK_STREAM, 0);


    // 소켓 설정

    addrSockSvr.sin_family = AF_INET;

    addrSockSvr.sin_port = htons(12345);

    addrSockSvr.sin_addr.S_un.S_addr = INADDR_ANY;

    bind(sockSvr, (struct sockaddr *)&addrSockSvr, sizeof(addrSockSvr));


    // TCP클라이언트로 부터 접속 요구를 대기

    listen(sockSvr, 5);


    // TCP클라이언트로 부터 접속 요구 받기

    nlen = sizeof(addrSockclt);

    sockSS = accept(sockSvr, (struct sockaddr *)&addrSockclt, &nlen);


    // 문자송신

    send(sockSS, "Hello TCP/IP world", 18, 0);


    // TCP세션 종료

    closesocket(sockSS);


    // 윈속 종료

    WSACleanup();


    return 0;


}


======================================================================


----------------------------------------------------------------------

초간단 TCP클라이언트

윈속을 사용한 초간단 클라이언트 소스.
코드의 간략화를 위해 에러처리 생략

======================================================================

#include <stdio.h>

#include <winsock2.h>


int main()

{

    WSADATA    wsaData;

    SOCKET    sockClt;

    char    szMsg[32];

    struct sockaddr_in addrSockSvr;


    // 윈속 초기화

    WSAStartup(MAKEWORD(2, 0), &wsaData);


    // 소켓 만들기

    sockClt = socket(AF_INET, SOCK_STREAM, 0);


    // 접속할 서버 설정

    addrSockSvr.sin_family = AF_INET;

    addrSockSvr.sin_port = htons(12345);

    addrSockSvr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");


    // 서버에 접속

    connect(sockClt, (struct sockaddr *)&addrSockSvr, sizeof(addrSockSvr));


    // 서버로 부터 데이터 수신

    memset(szMsg, 0, sizeof(szMsg));

    int nLet = recv(sockClt, szMsg, sizeof(szMsg), 0);


    printf("%s\n", szMsg);


    // 윈속 종료

    WSACleanup();


    return 0;

}


======================================================================

서버 프로그램을 실행시키고 클라이언트 프로그램을 실행시키면
서버로 부터 문자를 수신해서 printf한다.
Comments