티스토리 뷰

1.socket 함수 구현

 

 

Socket(int __domain, int __type, int __protocol)

 

이 함수는 사실 필요 없다. 

소켓을 생성해주는 함수인데 그냥 listenfd = socket~~ 이 줄만 있으면 된다.

그 밑에 listenfd 값이 -1이면 에러를 출력한다.

 

 

2.Bind 함수 구현

 

 

void Bind(int __fd, inaddr *__addr, socklen_t __len)

 

int __fd : listenfd를 의미한다.

inaddr *__addr : sockaddr_in 구조체 변수의 주소를 의미한다.

socklen_t __len : 구조체 변수의 크기를 의미함.

 

리턴값이 -1이면 에러를 출력한다.

 

3.Listen 함수 구현

 

void Listen(int __fd,int __n)

 

int __fd : listenfd를 의미한다.

int __n : 대기 시간을 의미한다.

 

리턴값이 -1일 경우 에러를 출력한다.

 

4.Accept 함수 구현

 

int __fd : listenfd 값을 의미한다.

saddr* __addr : 클라이언트에 대한 주소 정보를 담는다.

socklen_t *__addr_len : 주소 정보의 크기를 의미한다.

 

connfd : accept함수로 클라이언트와의 연결.

 

connfd가 -1 경우 에러 출력.

 

5.bind에서 사용할 구조체 선언.

 

listenAddr함수에 port번호를 인자로 전달한다.

 

inaddr servaddr : 구조체 변수선언.

bzero : 구조체 변수 servaddr의 값을 0으로 초기화.

servaddr .sin_family를 AF_INET으로 초기화.

servaddr.sin_port를 port값으로 초기화.

servaddr.sin_addr.s_addr를 무작위 호스트로 초기화.

 

구조체 변수 리턴.

 

6.main 함수

 

 

Socket함수를 사용할 필요 없이 listenfd = socket~으로 초기화.

 

servaddr 구조체 변수에 listenAddr(10000)으로 포트 10000번 지정.

 

Bind함수로 listenfd 소켓과 구조체 변수 servaddr를 사용해 묶는다.

 

Listen함수로 listenfd 소켓에서 5초의 지연시간을 가진다.

 

sockaddr 구조체 변수 clientaddr 선언.

구조체 길이 clientaddlen 선언.

clientaddr을 0으로 초기화.

inaddr 구조체 변수 caddr_in 변수 선언.

 

connfd 디스크립터로 Accept 함수 리턴 값 받아주기. 

Accept함수는 listenfd 소켓에 clientaddr 구조체 변수와 clientaddlen 길이를 accept 해준다.

 

memcpy 함수로 clientaddr 주소 값을 caddr_in에 복사한다.

 

close(listenfd)로 listen 상태를 끊는다. 현재 연결이 성립되었으니 굳이 listen할 필요가 없기 때문이다.

 

write함수로 메세지를 전달하고,

close(connfd)로 연결을 종료한다.

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

char z = '1';

// Wrapper Functions
typedef struct sockaddr_in inaddr;
typedef struct sockaddr saddr;

int Socket(int __domain, int __type, int __protocol)
{
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1)
    {
        fprintf(stderr, "Listen Socket Open Error!: %s", strerror(errno));
    }
    return listenfd;
}

void Bind(int __fd, inaddr *__addr, socklen_t __len)
{
    if (bind(__fd, (struct sockaddr *)__addr, __len) == -1)
    {
        fprintf(stderr, "Bind Error!: %s", strerror(errno));
    }
}

void Listen(int __fd, int __n)
{
    if (listen(__fd, __n) == -1)
    {
        fprintf(stderr, "Socket Listening Error!: %s", strerror(errno));
    }
}

int Accept(int __fd, saddr* __addr, socklen_t *__addr_len)
{
    int connfd = accept(__fd, __addr, __addr_len);
    if (connfd == -1)
    {
        fprintf(stderr, "Accept Error!: %s", strerror(errno));
    }

    return connfd;
}

inaddr listenAddr(int port)
{
    inaddr servaddr;
    bzero(&servaddr, sizeof(servaddr)); //memset(&servaddr, 0, sizeof(servaddr)); 와 동일
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    // (LE) 입력값: "0010 0111" '0001 0000'
    // (BE) 결과값: '0001 0000' "0010 0111"
    // 실제 결과값: '0001 0000' "0010 0111"
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    return servaddr;
}

int main()
{
    int x = 1;

    int listenfd = socket(AF_INET, SOCK_STREAM, 0);

    inaddr servaddr = listenAddr(10000);
    Bind(listenfd, &servaddr, sizeof(servaddr));
    Listen(listenfd, 5);

    struct sockaddr clientaddr;
    socklen_t clientaddlen;
    bzero(&clientaddr, sizeof(clientaddr)); // 구조체 초기화
    inaddr caddr_in;

    int connfd = Accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddlen);
    // accept의 두 번째 인자와 세 번째 인자가 각각
    // 상대방의 주소에 관한 구조체와 그 구조체의 크기 (byte 단위)
    // (LE) '0000 0001' '0000 0000' '0000 0000' '0111 1111'
    // (BE) '0111 1111' '0000 0000' '0000 0000' '0000 0001' 127 0 0 1
    memcpy(&caddr_in, &clientaddr, sizeof(caddr_in));
    // (BE) 입력값: "1000 1011" '0000 1110'
    // (LE) 결과값: '0000 1110' "1000 1011"
    close(listenfd);
    printf("sockaddr length: %ld sockaddr_in length: %ld\n", sizeof(struct sockaddr), sizeof(struct sockaddr_in));
    printf("Client IP Address in hexadecimal: %x\n", ntohl(caddr_in.sin_addr.s_addr));
    printf("Client Port in hexadecimal: %x\n", ntohs(caddr_in.sin_port));

    // 연결 수립
    write(connfd, "Hello", 6);

    close(connfd);

    printf("Server: All done");

    return 0;
}

'네트워크' 카테고리의 다른 글

[네트워크]TCP에 관하여  (0) 2021.04.08
라우팅  (0) 2021.03.29
C socket 프로그래밍 수업 1주차  (0) 2021.03.22
IPSEC  (0) 2020.10.16
DNS 쿼리  (0) 2020.10.14
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함