본문 바로가기
Study/ETC & TIP

Linux용 소켓프로그램

by Answer Choi 2015. 10. 29.
반응형

바탕이 되는 기본 소스코드는 요우님의 블로그를 참고하였고, 함수에 대한 설명은 falinux를 


참고하였습니다.


먼저 만들고 싶은 소켓의 구조는 아래와 같습니다.



중간의 Middle Ware를 만들어 볼껀데, Server는 외부에 있고, Client와 Middle Ware는 같이 있습니다.


M/W가 서버로 Port 9998번을 항상 열고 대기하고 있으며, Client가 9998번 포트로 붙어서 데이터를 


전송하면 M/W는 Client의 접속을 끊고 Server에 9997번 포트로 접소하여 데이터를 보냅니다.


Server는 데이터를 받고 Client로 보낼 데이터가 없으면 null, 있으면 데이터를 M/W로 보냅니다.


M/W는 Server의 데이터를 수신한 후 연결을 끊고, null이 아닐경우 Client에 9999 포트로 접속해서 


데이터를 전송하고, Client가 데이터를 수신한 후 연결을 끊는 구조입니다.


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
if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)// create server socket
    {
        printf("Server : Can't open stream socket\n");//if failed
        exit(0);
    }
    
    bzero((char *)&server_addr, sizeof(server_addr));//server_Addr initialize to null
    //server_addr setting
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(mw_port);
 
 
    if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) <0)//bind
    {
        printf("Server : Can't bind local address.\n");//if failed
        exit(0);
    }
 
    if(listen(server_fd, numofclient) < 0)//listening
    {
        printf("Server : Can't listening connect.\n");    //if failed
        exit(0);
    }
 
    //successfully create server
    bzero(buffer, sizeof(buffer));    //buffer initialize
    
    printf("Server: Starting DR M/W\n");
    len = sizeof(client_addr);
cs


이 부분이 M/W가 서버로 리스닝상태로 들어가는 부분입니다.


Line 1~5 : 소켓을 생성하는 부분입니다.



socket 함수를 보면 첫번째 인자는 통신방법, 두번째는 데이터 전송방식을 사용 할 것인지


세번째는 프로토콜인데 보통 0을 사용합니다.


저는 IPv4에  TCP방식으로 socket을 생성했습니다.


Line 7~11 : socket에 연결할 socket 관련 설정을 합니다.


구조체 sockaddr_in 을 이용해서 하는데, ipv6의 경우 sockaddr_in6를 써야 합니다.


뒤에 붙는 매게변수는 위와 같습니다.


주의 하실점은 port의 경우 int형으로 쓰실경우 htons 함수를 이용해야 합니다.


그래야 인식할 수 있습니다.


addr의 경우도 network용으로 변환해 줘야 합니다.


Line 14~18 : binding을 합니다.



서버로 사용하기 위해 설정한 socket을 등록해주는 단계입니다.


앞서 설정한 socket과 sockaddr_in을 인자로 넣어줍니다.


만약 실패하면 -1을 리턴받습니다.


Line 20~24 : listening을 시작합니다.



listen은 접속을 기다리는 함수입니다.


인자로 socket과 접속할 수 있는 클라이언트 수를 넣어줍니다.


실패시 -1을 리턴 받습니다.


Line 27~30 : 주고 받을 버터와 client를 리셋해 줍니다.


※ bzero 함수는 버퍼초기화 함수 입니다.


memset은 특정값으로 초기화를 하지만, bzero는 0으로 초기화 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while(1)    //listening forever
{
    if((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &len))<0)//accept client
    {
        printf("Server: accept failed.\n");    //if failed
        exit(0);
    }
    inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, temp, sizeof(temp));
    printf("Server : %s connected.\n", temp);//show connecting client ip
    bzero(buffer, sizeof(buffer));    //buffer initialize
    msg_size = read(client_fd, buffer, 1024);    //receive data from client
    printf("Server: receive msg : %s\n",buffer);
    close(client_fd);    //disconnect client
    printf("Server : %s client closed.\n", temp);
}
cs


이 부분은 클라이언트와 접속하고 통신을 하는 부분입니다.


Line 3~7 : 클라이언트의 접속을 기다립니다.



accept함수는 인자로 socket과 sockaddr_in 그리고 길이정보를 받게되며,


실패시 -1을 반환합니다.


Line 8~9 : 접속한 client의 주소값을 temp에 저장하고 화면에 보여줍니다.


Line 10~12 : client가 보낸 데이터를 받아서 화면에 보여줍니다.


Line 13 : client의 접속을 종료합니다.


여기까지가 서버로써의 역할이고, 이제부터는 클라이언트가 되어 다른 서버에 접속하는 과정입니다.


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
if(msg_size>0)//receive msg,send msg to db server
{
    if((dbServer_fd=socket(PF_INET,SOCK_STREAM,0))<0)    //create socket
    {
        printf("can't create db_mw socket\n");//if failed
        //exit(0);
    }
    bzero((char *)&dbServer_addr, sizeof(dbServer_addr));  //socket initialize
    dbServer_addr.sin_family = AF_INET;  //ipv4
    dbServer_addr.sin_addr.s_addr = inet_addr("192.168.0.101");  //db m/w ip address
    dbServer_addr.sin_port = htons(db_port);   //port
 
    if(connect(dbServer_fd, (struct sockaddr *)&dbServer_addr, sizeof(dbServer_addr)) < 0)//connecting db_mw server
    {
        printf("can't connect db_mw.\n");    //if failed
        //exit(0);
    }
    else    //connect successfully
    {
        printf("send msg %s\n",buffer);
        write(dbServer_fd, buffer, msg_size); //send data to dbserver
        bzero(buffer, sizeof(buffer));    //buffer initialize
        msg_size = read(dbServer_fd, buffer, 1024);
        printf("receive msg %s\n",buffer);    //receive data from dbserver
        close(dbServer_fd);    //db m/w disconnect
        printf("Server : %s db mw closed.\n", temp);
    }
}
cs


Line 3~11 : 이 부분은 앞서 서버로 설정할 때와 같습니다. 


Line 10 : client이기 때문에 접속할 server의 주소를 넣어줍니다.


Line 13~17 : 서버에 접속합니다.


역시 접속 실패시 -1을 반환받게 됩니다.


Line 20~21 : 접속이 되면 서버에 데이터를 보냅니다.


Line 22~24 : 버퍼를 초기화 한 후 서버로부터 데이터를 받습니다.


Line 25 : 서버 접속을 종료합니다.


반응형

인기글