[c] window TCP/IP socket code(*.c, TCPIP 소켓 코드)

2021. 12. 17. 14:40Language/c

728x90
728x90

[c언어] 윈도우 tcp/ip client socket(클라이언트 소켓), tcp/ip server socket(서버 소켓) 메시지(message) 송신, 수신(send/recv) 코드 예제


-tcp/ip 예제 플로우 & 로직 설명.(client socket & server socket 한개의 노드에서 실행됨.)

 

-사전에 수행되어야 하는 작업.

  • gcc 컴파일러 설치되어있어야 함.
  • 글쓴이는 MinGW 툴로 컴파일 수행함.

-window tcp/ip server socket 코드(tcpip_server_socket.c)

#include <sys/types.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <WinSock2.h>

#define BUFFSIZE 1024
#define PORT 40966
#define MSG "serverMsg"

int main(int argc, char **argv)
{
    //winsock 2.2ver
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    { 
        printf("can not connect WSA\n");
        exit(1);
    }
    
    //set msg
    char send_msg[BUFFSIZE], recv_msg[BUFFSIZE];

    //make server socket
    int server_socket, client_socket, client_addr_size;
    int opt, len;
    struct sockaddr_in server_addr, client_addr;
    server_socket = socket(PF_INET, SOCK_STREAM, 0);
    if (server_socket < 0)
    {
        printf("(I) socket error!!!\n");
        exit(1);
    }

    opt = 1;
    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);

    //bind
    if (-1 == bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)))
    {
        printf("(E) accept() error!!!\n");
        close(server_socket);
        exit(1);
    }
    printf("(I) bind success...\n");

    //listen
    if (-1 == listen(server_socket, 5))
    {
        printf("(E) listen() error!!!\n");
        close(server_socket);
        exit(1);
    }
    printf("(I) listen success[port:%d]\n\n", PORT);
    client_addr_size = sizeof(client_addr);
	
    while(1)
    {
    	//accept
        printf("(I) waitting to accept...\n");
        client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_size);
        if (client_socket < 0)
        {
            printf("(E) accept() error!!!\n");
            close(server_socket);
            exit(1);
        }
        printf("(I) connection accepted[%d]...\n", client_socket);

	//recv_send
        for(int i = 0; i < 1; i++)
        {
            memset(send_msg, 0x00, sizeof(send_msg));
            memset(recv_msg, 0x00, sizeof(recv_msg));

            len = recv(client_socket, recv_msg, BUFFSIZE, 0);
            if (len < 0)
            {
                printf("(E) recv() error[%d]!!!\n", len);
                close(client_socket);
                close(server_socket);
                exit(1);
            } else if (len == 0) {
                break;
            } 

            printf("(I) recv[%04d][%.*s]\n", len, len, recv_msg);
            strcpy(send_msg, MSG);
            len = send(client_socket, send_msg, len, 0);
            
            if (len < 0)
            {
                printf("(E) send() error[%d]!!!\n", len);
                close(client_socket);
                close(server_socket);
                exit(1);
            }
            printf("(I) send[%04d][%.*s]\n\n", len, len, send_msg);
        }
        close(client_socket);
    }

    close(client_socket);
    close(server_socket);

    return 0;
}

-window tcp/ip client socket 코드(tcpip_client_socket.c)

#include <sys/types.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <WinSock2.h>

#define BUFFSIZE 1024
#define IP_ADDR "127.0.0.1"
#define PORT 40966
#define MSG "clientMsg"

int main(int argc, char **argv)
{
    //winsock 2.2ver
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
    {
        printf("can not connect WSA\n");
        exit(1);
    }
    
    //set time
    char timebuff[50] = {0};
    struct tm *ptm;
    time_t now;
    now = time(NULL);
    ptm = localtime(&now);
    strftime(timebuff, sizeof(timebuff), "%Y-%m-%d %H:%M:%S", ptm);

    //set msg
    char send_msg[BUFFSIZE], recv_msg[BUFFSIZE];

    //make client socket
    int client_socket, len;
    struct sockaddr_in server_addr;
    client_socket = socket(PF_INET, SOCK_STREAM, 0);
    if (client_socket < 0)
    {
        printf("(E) socket() error!!!\n");
        exit(1);
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(IP_ADDR);
    server_addr.sin_port = htons(PORT);
    
    //connect
   if (-1 == connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)))
    {
        printf("(E) connect() error[IP:%s, PORT:%d]\n", IP_ADDR, PORT);
        exit(1);
    }
    printf("(I) socket connect...[%s:%d]\n", IP_ADDR, PORT);

    memset(send_msg, 0x00, sizeof(send_msg));
    memset(recv_msg, 0x00, sizeof(recv_msg));
    strcpy(send_msg, MSG);
	
    //send_recv
    for (int i = 0; i < 1; i++)
    {
        len = strlen(send_msg);
        len = send(client_socket, send_msg, len, 0);
        if (len < 0)
        {
            printf("(E) send() error[%d]!!!\n", len);
            close(client_socket);
            exit(1);
        }
        printf("send time : %s\n", timebuff);
        printf("(I) send[%04d][%.*s]\n", len, len, send_msg);
        
        len = recv(client_socket, recv_msg, len, 0);
        if (len < 0)
        {
            printf("(E) recv() error[%d]!!!\n", len);
            close(client_socket);
            exit(1);
        }
        else if (len == 0)
        {
            printf("(W) socket closed...[%d]!!!\n", len);
            close(client_socket);
            exit(1);
        }
        printf("recv time : %s\n", timebuff);
        printf("(I) recv[%04d][%.*s]\n\n", len, len, recv_msg);
    }

    close(client_socket);

    return 0;
}

-window tcp/ip server socket 컴파일(warning 무시)

$ gcc -o tcpip_server_socket.exe tcpip_server_socket.c -lws2_32 -Wall

-window tcp/ip client socket 컴파일(warning 무시)

$ gcc -o tcpip_client_socket.exe tcpip_client_socket.c -lws2_32 -Wall

-window tcp/ip server socket 실행(방화벽 팝업 출력시, access 허용해야 .)

$ .\tcpip_server_socket

-window tcp/ip client socket 실행(방화벽 팝업 출력시, access 허용해야 .)

$ .\tcpip_client_socket

-window tcp/ip server socket 실행 결과.

(I) bind success...
(I) listen success[port:40966]
(I) waitting to accept…
(I) connection accepted[152]…

(I) recv[0009][clientMsg]
(I) send[0009][serverMsg]

(I) waitting to accept...

-window tcp/ip client socket 실행 결과.

(I) socket connect...[127.0.0.1:40966]
send time : 2021-12-17 14:29:12
(I) send[0009][clientMsg]
recv time : 2021-12-17 14:29:12
(I) recv[0009][serverMsg]
728x90
728x90