본문 바로가기
코스웨어/15년 스마트컨트롤러

20151130 수업 / winsock_1 - 남수진

by 알 수 없는 사용자 2015. 11. 30.
728x90
반응형

Winsock

  • 필요한 헤더파일/라이브러리
    • winsock.h
      • #pragma comment(lib, "wsock32.lib")
    • Winsock2.h
      • #pragma comment(lib, "ws2_32.lib")
    • gcc에서도 라이브러리를 추가해야하지만 상위 버전의 gcc에서는 라이브러리를 생략해도 컴파일된다

 

  • 시작과 끝에 WSA 함수를 붙인다
    • 윈도우에서 소켓을 사용하기위해 반드시 불러야 하는 함수
    • 시작: WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
      • wVersionRequested :  winsock 버전
    • 끝:     WSACleanup()

 

  • SOCKET socket(int af, int type, int protocol)
    • SOCKET = unsigned int

 

  • 네트워크 정보 구조체 세팅
    • struct sockaddr_in(SOCKADDR_IN)
    • 포트 = htons(PORT)
      • htons: little endian -> big endian
    • 아이피 = inet_addr(IP)
      • inet_addr: 아이피 변환함수
      • INADDR_ANY
        • 0으로 define되어 있어 자기 컴퓨터 IP로 IP가 세팅된다
        • htonl을 사용해서 변환

 

  • bind
    • 구조체에 저장한 네트워크 정보를 소켓에 세팅

 

  • listen
    • 클라이언트 수신 대기

 

  • 접속한 클라이언트 정보 저장
    • 서버에서 사용한 구조체를 재활용해도 된다

 

  • 클라이언트와 통신
    • recv() - 수신
    • send() - 송신

DRW00001ee841f6

 

서버

#include <stdio.h>
#include <winsock.h>

#pragma comment(lib, "wsock32.lib")
#define PORT    7777
#define IP    "192.168.0.201"

int main(void)
{
    WSADATA wsaData;
    SOCKET sSock;
    SOCKET cSock;
    SOCKADDR_IN sAddr;
    char ReadBuffer[256];
    int iLen;

    if(WSAStartup(MAKEWORD(2,2),&wsaData)!= 0)
    {
        printf("Error\n");
        return 0;
    }

    sSock = socket(AF_INET, SOCK_STREAM, 0);
    if( INVALID_SOCKET == sSock)
    {
        printf("socket() Error\n");
        WSACleanup();
        return 0;
    }   

    memset(&sAddr, 0, sizeof(SOCKADDR_IN));
    sAddr.sin_family = AF_INET;
    sAddr.sin_port = htons(PORT);
    // INADDR_ANY(=0)을 넣으면 자기 IP 사용
    // sAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    sAddr.sin_addr.S_un.S_addr = inet_addr(IP);

    if( SOCKET_ERROR == bind(sSock, (SOCKADDR *)&sAddr, sizeof(SOCKADDR_IN)))
    {
        printf("bind() Error\n");
        closesocket(sSock);
        WSACleanup();
        return 0;
    }
    if( SOCKET_ERROR == listen( sSock, 5 ))
    {
        printf("listen() Error\n");
        closesocket(sSock);
        WSACleanup();
        return 0;
    }
    memset(&sAddr, 0, sizeof(SOCKADDR_IN));
    iLen = sizeof(SOCKADDR_IN);
    cSock = accept(sSock, (SOCKADDR *)&sAddr, &iLen);
    if(cSock == INVALID_SOCKET)
    {
        printf("accept() Error\n");
        closesocket(sSock);
        WSACleanup();
        return 0;
    }
    printf("Incoming Client: [%s]:[%d]\n", inet_ntoa(sAddr.sin_addr), PORT);

    while(1)
    {
        iLen = recv(cSock, ReadBuffer, 255, 0);
        if(0 < iLen)
        {
            send(cSock, ReadBuffer, 255, 0);
        }
        else
        {
            printf("Read error\n");
        }
       
        if(0 == strncmp(ReadBuffer, "quit", 4))
        {
            break;
        }
    }

    closesocket(sSock);
    WSACleanup();
    return 0;
}

 

클라이언트

#include <stdio.h>
#include <winsock.h>

#pragma comment(lib, "wsock32.lib")
#define PORT    7777
#define IP    "192.168.0.201"

int main(void)
{
    WSADATA wsaData;
    SOCKET cSock;
    SOCKADDR_IN sAddr;
    char ReadBuffer[256];
    int iLen;

    if(WSAStartup(MAKEWORD(2,2),&wsaData)!= 0)
    {
        printf("Error\n");
        return 0;
    }

    cSock = socket(AF_INET, SOCK_STREAM, 0);
    if( INVALID_SOCKET == cSock)
    {
        printf("socket() Error\n");
        WSACleanup();
        return 0;
    }   

    memset(&sAddr, 0, sizeof(SOCKADDR_IN));
    sAddr.sin_family = AF_INET;
    sAddr.sin_port = htons(PORT);
    // INADDR_ANY(=0)을 넣으면 자기 IP 사용
    // sAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    sAddr.sin_addr.S_un.S_addr = inet_addr(IP);

    if( SOCKET_ERROR == connect(cSock, (SOCKADDR *)&sAddr, sizeof(SOCKADDR_IN)))
    {
        printf("connect() Error\n");
        closesocket(cSock);
        WSACleanup();
        return 0;
    }
    printf("Connected\n");

    while(1)
    {
        iLen = read(0, ReadBuffer, 256);
        ReadBuffer[iLen] = 0;
        send(cSock, ReadBuffer, 255, 0);
        iLen = recv(cSock, ReadBuffer, 255, 0);
        printf("echo: %s", ReadBuffer);
       
        if(0 == strncmp(ReadBuffer, "quit", 4))
        {
            break;
        }
    }

    closesocket(cSock);
    WSACleanup();
    return 0;
}

 

image

728x90