//IPC QUEUE 데이타를 읽어 KAFKA에 전송하는경우

//FILE의 데이타를 읽어서 KAFKA에 전송하는경우(아래소스는 여기에 해당)

/*

* librdkafka - Apache Kafka C library

*

* Copyright (c) 2017, Magnus Edenhill

* All rights reserved.

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions are met:

*

* 1. Redistributions of source code must retain the above copyright notice,

*    this list of conditions and the following disclaimer.

* 2. Redistributions in binary form must reproduce the above copyright notice,

*    this list of conditions and the following disclaimer in the documentation

*    and/or other materials provided with the distribution.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE

* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

* POSSIBILITY OF SUCH DAMAGE.

*/

 

/**

* Simple Apache Kafka producer

* using the Kafka driver from librdkafka

* (https://github.com/edenhill/librdkafka)

*/

 

#include <stdio.h>

#include <signal.h>

#include <string.h>

 

 

/* Typical include path would be <librdkafka/rdkafka.h>, but this program

* is builtin from within the librdkafka source tree and thus differs. */

#include "rdkafka.h"

 

static int run = 1;

 

/**

* @brief Signal termination of program

*/

static void stop (int sig) {

    run = 0;

    fclose(stdin); /* abort fgets() */

}

 

 

/**

* @brief Message delivery report callback.

*

* This callback is called exactly once per message, indicating if

* the message was succesfully delivered

* (rkmessage->err == RD_KAFKA_RESP_ERR_NO_ERROR) or permanently

* failed delivery (rkmessage->err != RD_KAFKA_RESP_ERR_NO_ERROR).

*

* The callback is triggered from rd_kafka_poll() and executes on

* the application's thread.

*/

static void dr_msg_cb (rd_kafka_t *rk, const rd_kafka_message_t *rkmessage, void *opaque) {

    if (rkmessage->err)

        fprintf(stderr, "%% Message delivery failed: %s\n",

        rd_kafka_err2str(rkmessage->err));

    else

        fprintf(stderr,"%% Message delivered (%zd bytes, ""partition %"PRId32")\n",rkmessage->len, rkmessage->partition);

    /* The rkmessage is destroyed automatically by librdkafka */

}

 

int main (int argc, char **argv) {

    rd_kafka_t *rk;         /* Producer instance handle */

    rd_kafka_topic_t *rkt;  /* Topic object */

    rd_kafka_conf_t *conf;  /* Temporary configuration object */

    char errstr[512];       /* librdkafka API error reporting buffer */

    char buf[512];          /* Message value temporary buffer */

    const char *brokers;    /* Argument: broker list */

    const char *topic;      /* Argument: topic to produce to */

 

    FILE *fp=NULL;

 

    /*

     * Argument validation

     */

    if (argc != 4) {

        fprintf(stderr, "%% Usage: %s <broker> <topic> <filename>\n", argv[0]);

        return -1;

    }

 

    brokers = argv[1];   //127.0.0.1:9092

 

    //1.1 기본적인 topic 생성예제(topic의 이름은 test)

    //>bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

    //1.2 일자별로 topic생성(아래예제는 20180401 ~ 20180431, 4월 날짜별로 topic생성)

    //>for ii in `seq 20180401 20180431`; do bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic $ii; done

 

    //3. Step 3: Create a topic

    //3.1 Let's create a topic named "test" with a single partition and only one replica:

    // for ii in `seq 20180411 20180431`; do bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic $ii; done

    //> cd /home1/irteamsu/kafka2/kafka_2.11-1.1.0

    //> bin/kafka-server-start.sh config/server.properties

    //3.2 TOPIC리스트 확인

    //> bin/kafka-topics.sh --list --zookeeper localhost:2181

    

    topic   = argv[2];   //YYYYMMDD

 

    if((fp=fopen(argv[3], "rt"))==NULL) return(-1);

    /*

     * Create Kafka client configuration place-holder

     */

    conf = rd_kafka_conf_new();

 

    /* Set bootstrap broker(s) as a comma-separated list of

     * host or host:port (default port 9092).

     * librdkafka will use the bootstrap brokers to acquire the full

     * set of brokers from the cluster. */

    if (rd_kafka_conf_set(conf, "bootstrap.servers", brokers,errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK) 

    {

        fprintf(stderr, "%s\n", errstr);

        return -1;

    }

 

    /* Set the delivery report callback.

     * This callback will be called once per message to inform

     * the application if delivery succeeded or failed.

     * See dr_msg_cb() above. */

    rd_kafka_conf_set_dr_msg_cb(conf, dr_msg_cb);

 

 

    /*

     * Create producer instance.

     *

     * NOTE: rd_kafka_new() takes ownership of the conf object

     *       and the application must not reference it again after

     *       this call.

     */

    rk = rd_kafka_new(RD_KAFKA_PRODUCER, conf, errstr, sizeof(errstr));

    if (!rk) {

        fprintf(stderr,

            "%% Failed to create new producer: %s\n", errstr);

        return -1;

    }

 

 

    /* Create topic object that will be reused for each message

     * produced.

     *

     * Both the producer instance (rd_kafka_t) and topic objects (topic_t)

     * are long-lived objects that should be reused as much as possible.

     */

    rkt = rd_kafka_topic_new(rk, topic, NULL);

    if (!rkt) {

        fprintf(stderr, "%% Failed to create topic object: %s\n",

        rd_kafka_err2str(rd_kafka_last_error()));

        rd_kafka_destroy(rk);

        return -1;

    }

 

    /* Signal handler for clean shutdown */

    signal(SIGINT, stop);

 

    fprintf(stderr,

        "%% Type some text and hit enter to produce message\n"

        "%% Or just hit enter to only serve delivery reports\n"

        "%% Press Ctrl-C or Ctrl-D to exit\n");

 

    while (run) 

    {

        memset(buf, 0x00, sizeof(buf));

        if(fgets(buf, sizeof(buf), fp)==NULL) break;

 

        size_t len = strlen(buf);

 

        if (buf[len-1] == '\n') /* Remove newline */

        buf[--len] = '\0';

 

        if (len == 0) {

            /* Empty line: only serve delivery reports */

            rd_kafka_poll(rk, 0/*non-blocking */);

            continue;

        }

 

    /*

     * Send/Produce message.

     * This is an asynchronous call, on success it will only

     * enqueue the message on the internal producer queue.

     * The actual delivery attempts to the broker are handled

     * by background threads.

     * The previously registered delivery report callback

     * (dr_msg_cb) is used to signal back to the application

     * when the message has been delivered (or failed).

     */

    retry:

        if (rd_kafka_produce(

            /* Topic object */

            rkt,

            /* Use builtin partitioner to select partition*/

            RD_KAFKA_PARTITION_UA,

            /* Make a copy of the payload. */

            RD_KAFKA_MSG_F_COPY,

            /* Message payload (value) and length */

            buf, len,

            /* Optional key and its length */

            NULL, 0,

            /* Message opaque, provided in

             * delivery report callback as

             * msg_opaque. */

            NULL) == -1)

        {

            /**

             * Failed to *enqueue* message for producing.

             */

            fprintf(stderr,

            "%% Failed to produce to topic %s: %s\n",

            rd_kafka_topic_name(rkt),

            rd_kafka_err2str(rd_kafka_last_error()));

 

            /* Poll to handle delivery reports */

            if (rd_kafka_last_error() ==

                RD_KAFKA_RESP_ERR__QUEUE_FULL) {

                /* If the internal queue is full, wait for

                 * messages to be delivered and then retry.

                 * The internal queue represents both

                 * messages to be sent and messages that have

                 * been sent or failed, awaiting their

                 * delivery report callback to be called.

                 *

                 * The internal queue is limited by the

                 * configuration property

                 * queue.buffering.max.messages */

                rd_kafka_poll(rk, 1000/*block for max 1000ms*/);

                goto retry;

            }

        

        else 

        {

            fprintf(stderr, "%% Enqueued message (%zd bytes) "

                "for topic %s\n",

                len, rd_kafka_topic_name(rkt));

        }

 

 

        /* A producer application should continually serve

         * the delivery report queue by calling rd_kafka_poll()

         * at frequent intervals.

         * Either put the poll call in your main loop, or in a

         * dedicated thread, or call it after every

         * rd_kafka_produce() call.

         * Just make sure that rd_kafka_poll() is still called

         * during periods where you are not producing any messages

         * to make sure previously produced messages have their

         * delivery report callback served (and any other callbacks

         * you register). */

        rd_kafka_poll(rk, 0/*non-blocking*/);

    }

 

    /* Wait for final messages to be delivered or fail.

     * rd_kafka_flush() is an abstraction over rd_kafka_poll() which

     * waits for all messages to be delivered. 

     */

    fprintf(stderr, "%% Flushing final messages..\n");

    rd_kafka_flush(rk, 10*1000 /* wait for max 10 seconds */);

 

    /* Destroy topic object */

    rd_kafka_topic_destroy(rkt);

 

    /* Destroy the producer instance */

    rd_kafka_destroy(rk);

 

    return 0;

}

 

 

'통신 > THREAD(TCP)' 카테고리의 다른 글

RcvManualData.c  (0) 2021.03.17

/*

LINUX,SERVER,SELECT(RECV),SELECT(SEND)

LINUX,SERVER,SELECT(RECV),SELECT(SEND)

LINUX,SERVER,SELECT(RECV),SELECT(SEND)

LINUX,SERVER,SELECT(RECV),SELECT(SEND)

LINUX,SERVER,SELECT(RECV),SELECT(SEND)

LINUX,SERVER,SELECT(RECV),SELECT(SEND)

LINUX,SERVER,SELECT(RECV),SELECT(SEND)

LINUX,SERVER,SELECT(RECV),SELECT(SEND)

*/

 

#include <stdio.h>

#include <fcntl.h>

#include <stdlib.h>

#include <signal.h>

#include <sys/socket.h>

#include <sys/file.h>

#include <netinet/in.h>

#include <string.h>

 

#define MAXLINE 512

#define MAX_SOCK 64

 

char *escapechar = "exit";

 

int maxfdp1;

int g_num_chat = 0;

int s;

int client_s[MAX_SOCK];

 

static int getmax(int);

static void removeclient(int);

static int getdottedipaddr(int sd, struct sockaddr_in *addr);

static void my_signal(int signo);

 

int main(int argc, char *argv[]) 

{

    char rline[MAXLINE+1];

    char *start = "Connected to chat-server\n";

    int i, j, n;

    int client_fd, clilen;

 

    fd_set read_fds;

    struct sockaddr_in client_addr, server_addr;

 

    if (argc != 2) {

        printf("usage : %s port\n", argv[0]);

        return(-1);

    }

 

    if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {

        printf("can't open stream socket.");

        return(-2);

    }

 

    bzero((char *)&server_addr, sizeof(server_addr));

    server_addr.sin_family = AF_INET;

    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    server_addr.sin_port = htons(atoi(argv[1]));

 

    if (bind(s, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {

        printf("Server: Can't bind local address.\n");

        return(-3);

    }

 

    if (signal(SIGINT, my_signal) == SIG_ERR) { /* Ctrl+C */

        printf("Server: signal(SIGINT) error\n");

        return(-4);

    }

    if (signal(SIGTERM, my_signal) == SIG_ERR) { /* software termination */

        printf("Server: signal(SIGTERM) error\n");

        return(-5);

    }

    if (signal(SIGQUIT, my_signal) == SIG_ERR) { /* Ctrl+\ */

        printf("Server: signal(SIGQUIT) error\n");

        return(-6);

    }

 

 

    listen(s, 5); /* backlog = 5 */

 

    maxfdp1 = s + 1;

 

    while (1) 

    {

        FD_ZERO(&read_fds);

        FD_SET(s, &read_fds);

 

        for (ii=0; ii < g_num_chat; ii++)

        {

            FD_SET(client_s[ii], &read_fds);

}

        maxfdp1 = getmax(s) + 1; /* maxfdp1 재 계산 */

 

        /*wait & response*/

/*wait & response*/

/*wait & response*/

/*wait & response*/

/*wait & response*/

/*wait & response*/

/*wait & response*/

/*wait & response*/

        if (select(maxfdp1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) 

        {

            printf("select error.\n");

            break;

        }

 

        if (FD_ISSET(s, &read_fds)) 

        {

            clilen = sizeof(client_addr);

            client_fd = accept(s, (struct sockaddr *)&client_addr, &clilen);

            if (client_fd == -1) 

            {

                printf("server: accept error\n");

                break;

            }

 

            client_s[g_num_chat] = client_fd;

            g_num_chat++;

 

            /*welcome message*/

/*welcome message*/

/*welcome message*/

/*welcome message*/

/*welcome message*/

/*welcome message*/

/*welcome message*/

/*welcome message*/

            send(client_fd, start, strlen(start), 0);

 

            if (getdottedipaddr(client_fd, &client_addr) > -1)

                printf("%d number additional(IP: %s)\n", g_num_chat, inet_ntoa(client_addr.sin_addr));

            else

                printf("%d number additional\n", g_num_chat);

        }

        for (ii=0; ii<g_num_chat; ii++) 

        {

            if (FD_ISSET(client_s[ii], &read_fds)) 

            {

                if ((n = recv(client_s[ii], rline, MAXLINE, 0)) <= 0) 

                {

                    removeclient(ii); /* abrupt exit *//* abrupt exit *//* abrupt exit *//* abrupt exit */

                    continue;

                }

                rline[n] = '\0';

 

                if (strstr(rline, escapechar) != NULL) 

                {

                    removeclient(ii); /* abrupt exit *//* abrupt exit *//* abrupt exit *//* abrupt exit *//* abrupt exit */

                    continue;

                }

 

                for (kk=0; kk<g_num_chat; kk++)

                {

                    send(client_s[kk], rline, n, 0);

                }

 

                if (getdottedipaddr(client_fd, &client_addr) > -1)

                printf("IP: %s -> %s", inet_ntoa(client_addr.sin_addr), rline);

                else

                printf("%s", rline);

            }

        }

    } /* while */

    my_signal(SIGIO);

}

 

void removeclient(int indx) 

{

    struct sockaddr_in client_addr;

 

    if (getdottedipaddr(client_s[indx], &client_addr) > -1)

    printf("1 number expired!!(IP: %s).", inet_ntoa(client_addr.sin_addr));

    else

    printf("1 number expired!!.");

 

    close(client_s[indx]);

 

    if (indx != g_num_chat-1) client_s[indx] = client_s[g_num_chat-1];

 

    g_num_chat--;

    printf("now number = %d\n", g_num_chat);

}

 

int getmax(int k) {

 

    int max = k;

    int r;

 

    for (r=0; r < g_num_chat; r++)

    {

        if (client_s[r] > max) max = client_s[r];

    }

    return max;

}

 

/* 소켓에 연결된 상대방 주소를 알아낸다 */

int getdottedipaddr(int sd, struct sockaddr_in *addr) {

    struct sockaddr_in client_addr;

    int len, r;

 

    len = sizeof(client_addr);

    if ((r = getpeername(sd, (struct sockaddr *)&client_addr, &len)) == 0)

    {

        *addr = client_addr;

    }

    return r;

}

 

/* 시그널 처리 함수 정의 */

void my_signal(int signo) 

{

    int ii;

 

/* 대부분의 시그널(SIGILL과 SIGTRAP 은 제외)에 대한 처리 함수는 시그널이 포작된 후

즉시 재지정된다. 이것은 프로세스가 시그널의 처리 함수를 잊어버리고, 다음에 시그널이

도착하면 묵시적 처리함수인 SIG_DFL 을 수행하는 것을 의미한다.

이것은 특히 사용자가 인터럽트키를 여러번 누를 수도 있는 대화명 프로그램에서 문제가 된다

그러므로 시그널 함수가 호출되자 마자 SIGINT 시그널을 무시한다 */

    signal(SIGINT, SIG_IGN);

    signal(SIGTERM, SIG_IGN);

    signal(SIGQUIT, SIG_IGN);

 

    close(s);

    for (ii=0; ii < g_num_chat; ii++)

    {

        close(client_s[ii]);

    }

    exit(0);

}

/*----------------------------------------------------------------------------------------------------

socket function : accept

 

1. 소켓에 연결을 받아들인다.

#include <sys/types.h>

#include <sys/socket.h>

 

int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

 

2. 설명

accept() 함수는 연결지향 소켓 타입 (SOCK_STREAM, SOCK_SEQPACKET, SOCK_RDM)에 사용된다. 

이것은 아직 처리되지 않은 연결들이 대기하고 있는 큐에서 제일 처음 연결된 연결을 가져와서 새로운 연결된 소켓을 만든다. 

그리고 소켓을 가르키는 파일 지정자를 할당하고 이것을 리턴한다.

인자 s 는 socket() 로 만들어진 end-point(듣기 소켓)을 위한 파일지정자이다.

 

인자 addr 는 sockaddr 구조체에 대한 포인터이다. 

연결이 성공되면 이 구조체를 채워서 되돌려 주게 되고, 

우리는 이구조체의 정보를 이용해서 연결된 클라이언트의 인터넷 정보를 알아낼수 있다. addrlen 인자는 addr의 크기 이다.

 

만약 미결인 연결이 큐에 존재하지 않고, 소켓이 비봉쇄가 아니라면 accept 는 연결이 존재할때까지 해당영역에서 봉쇄된다. 

비봉쇄 소켓일경우에는 errno 로 EAGAIN 을 설정하고 바로 리턴한다.

 

3. 반환값

에러시 -1이 반환된다. 성공한다면 받아들인 소켓을 위한 파일지정번호 (0보다 큰)을 반환한다.

---------------------------------*/

/*

LINUX,MULTICAST,UDP SERVER

*/

 

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>

#include <errno.h>

#include <fcntl.h>

#include <signal.h>

#include <setjmp.h>

#include <unistd.h>

#include <ctype.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

#include  <sys/shm.h>

 

/*------------------------------------------------------------------------------------

TR_CODE DESC FRAME_ID         MULTICAST_GROUP REAL_PORT

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19711

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19712

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19713

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19714

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19715

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19716

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19717

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19718

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19719

A3012 체결 FID_KOSDAQCHEGYUL 233.37.54.51 19720

------------------------------------------------------------------------------------*/

 

/*USAGE------------------------------------------------------------------------------------

rcvmulticastdata 233.37.54.51 19711

rcvmulticastdata 233.37.54.51 19712

rcvmulticastdata 233.37.54.51 19713

rcvmulticastdata 233.37.54.51 19714

rcvmulticastdata 233.37.54.51 19715

rcvmulticastdata 233.37.54.51 19716

rcvmulticastdata 233.37.54.51 19717

..

..

..

..

------------------------------------------------------------------------------------*/

 

int main(int argc, char *argv[])

{

    int send_s, recv_s;             

    unsigned int yes=1, ttl=32;

    struct sockaddr_in mcast_group; 

 

    struct ip_mreq mreq;

    struct sockaddr_in from;

    int  rlen, len, rtn;

 

    if (argc != 3) {

        printf("usage : %s multicastaddr port &\n", argv[0]);

        exit(0);

    }

 

    for (;;)

    {

        //socket for multicast receive

        memset((char *)&mcast_group, 0, sizeof(mcast_group));

        mcast_group.sin_family = AF_INET;

        mcast_group.sin_port = htons(atoi(argv[2]));

        mcast_group.sin_addr.s_addr = inet_addr(argv[1]);

 

        if ((recv_s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 

        {

            printf("error: can't create receive socket\n");

            exit(0);

        }

 

        //multicast group register, and multicast network is defind by root user

        mreq.imr_multiaddr = mcast_group.sin_addr;

        //mreq.imr_interface.s_addr = htonl(INADDR_ANY);

        //"192.178.33.142" is multicast network interface

        mreq.imr_interface.s_addr = inet_addr("192.178.33.142");

 

        if (setsockopt(recv_s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) 

        {

            printf("error: add membership\n");

            exit(0);

        }

 

        //socket re-use option set

        if (setsockopt(recv_s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) 

        {

            printf("error: so_reuseaddr setsockopt\n");

            exit(0);

        }

 

        //socket bind

        if (bind(recv_s, (struct sockaddr*)&mcast_group, sizeof(mcast_group)) < 0) {

            printf("error: bind receive socket\n");

            exit(0);

        }

 

        for (;;)

        {

            len = sizeof(from);

            if ((rlen = recvfrom(recv_s, rbuf, SZ_MAX, 0, (struct sockaddr *)&from, &len)) < 0)

            {

                printf("error: recvfrom\n");

                exit(0);

            }

 

            rbuf[rlen] = '\0';

 

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

        }

        close(recv_s);

        usleep(1000);

    }

    return(0);

}

 

 

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

bash-3.1$
bash-3.1$ cat Makefile

CC = gcc

CFLAGS += -I./include/ -g -Wall -Wno-unused-variable
LIBS += -L. -lcurl -ljson-c -lwsock32

.c.o:
        $(CC) -c $< $(CFLAGS)

all: build

common.o : common.c
calc_server.o : calc_server.c
pushcall.o : pushcall.c
win_calc_server.o : win_calc_server.c

win_calc_server: win_calc_server.o pushcall.o common.o calc_server.o
        $(CC) -o $@ $^ $(LIBS)
BUILD_FILES += win_calc_server

build: $(BUILD_FILES)

clean:
        rm -f *.o
        rm -f $(BUILD_FILES)
bash-3.1$ make clean
rm -f *.o
rm -f win_calc_server
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$ make all
gcc -c win_calc_server.c -I./include/ -g -Wall -Wno-unused-variable
gcc -c pushcall.c -I./include/ -g -Wall -Wno-unused-variable
gcc -c common.c -I./include/ -g -Wall -Wno-unused-variable
gcc -c calc_server.c -I./include/ -g -Wall -Wno-unused-variable
gcc -o win_calc_server win_calc_server.o pushcall.o common.o calc_server.o -L. -lcurl -ljson-c -lwsock32
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$
bash-3.1$

 

 

 

 

 

#include <WinSock2.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

 

#define  MAXLINE 1024

 

DWORD WINAPI stdin_input_send_thread(LPVOID arg);

 

char line[MAXLINE], chatdata[MAXLINE+1];

 

struct sockaddr_in server_addr;

SOCKET clientsocket; //server connect socket

char *escape = "quit"; //exit command message

BOOL bisquit;           //exit falg variable

 

int main(int argc, char *argv[])

{

    WSADATA wsa;    //socket

    HANDLE hthread; //thread

    DWORD threadid;

    int size;

 

    if (argc != 3) 

    {

        printf("usage : %s server_address port\n", argv[0]);

        return(-1);

    }

    bisquit = FALSE;

 

    //socket initialization

    if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) 

    {

        return(-2);

    }

    //socket creation

    if ((clientsocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) 

    {

        printf("fail make socket\n");

        return(-3);

    }

 

    //memory initialization

    memset(&server_addr, 0x00, sizeof(server_addr));

    server_addr.sin_family = AF_INET;

    server_addr.sin_addr.s_addr = inet_addr(argv[1]);

    server_addr.sin_port = htons(atoi(argv[2]));

 

    //connection with server

    if (connect(clientsocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) 

    {

        printf("fail connect to server\n");

        return(-4);

    }

    else 

    {

        printf("connected server\n");

    }

 

 

    //stdin & send data thread creation

//stdin & send data thread creation

//stdin & send data thread creation

//stdin & send data thread creation

//stdin & send data thread creation

    hthread = CreateThread(NULL, 0, stdin_input_send_thread, 0, 0, &threadid);

    if (hthread == NULL) 

    {

        printf("fail make thread\n");

    }

    else 

    {

        CloseHandle(hthread);

    }

 

    while (!bisquit) 

    {

        memset(chatdata, 0x00, sizeof(chatdata));

 

        if ((size = recv(clientsocket, chatdata, MAXLINE, 0)) == INVALID_SOCKET) 

{

break;

}

else 

{

chatdata[size] = '\0';

printf("%s", chatdata);

}

    }

    closesocket(clientsocket);

    WSACleanup();

 

return(0);

}

 

//user data input mechanism

DWORD WINAPI stdin_input_send_thread(LPVOID arg)

{

    while(TRUE) 

    {

//stream read in stdin, input '\n' character is ended.

//stream read in stdin, input '\n' character is ended.

        if (fgets(chatdata, MAXLINE, stdin))

        {

            chatdata[strlen(chatdata) - 1] = 0x00;

            sprintf(line, "%s", chatdata);

 

if (strstr(line, escape) != 0) //exit command str

            {

                printf("GoodBye!!!!!!!\n");

                closesocket(clientsocket);

                bisquit = TRUE;

                return(-1);

            }

            

if (send(clientsocket, line, strlen(line), 0) < 0) 

            {

                printf("write fail\n");

return(-2);

            }

        }

    }

    return 0;

}

 

 

 

 

 

 

/*

WINDOWS,SOCKET,SELECT,SERVER,TCP

WINDOWS,SOCKET,SELECT,SERVER,TCP

WINDOWS,SOCKET,SELECT,SERVER,TCP,MULTI CHAT

WINDOWS,SOCKET,SELECT,SERVER,TCP,MULTI CHAT

WINDOWS,SOCKET,SELECT,SERVER,TCP,MULTI CHAT

WINDOWS,SOCKET,SELECT,SERVER,TCP,MULTI CHAT

*/

 

 

#include <stdio.h>

#include <fcntl.h>

#include <stdlib.h>

#include <winsock2.h>

#include <string.h>

 

#define MAXLINE 512

#define MAX_SOCK 64

 

#define bzero(b,len) (memset(b,0,len))

#define bcopy(b1,b2,len) (memcpy(b1,b2,len))

 

char *escapechar = "exit";

char send_calc_msg[MAXLINE+1];

 

//EXTERN LINK VARIABLE

char input[MAXLINE+1];

 

int maxfdp1;

int g_num_chat = 0;

int client_s[MAX_SOCK];

 

 

//STATIC LINK

static int getmax(int);

static void removeclient(int);

static int getdottedipaddr(int sd, struct sockaddr_in *addr);

 

//EXTERN LINK(calc_server.c)

int calculation_socket(char send_calc_msg[MAXLINE+1]);

//EXTERN LINK(pushcall.c)

int pushcall(void);

//EXTERN LINK(common.c)

int GetDate();

int GetTime();

 

int main(int argc, char *argv[]) 

{

    char rline[MAXLINE+1], send_calc_msg[MAXLINE+1];

    char *welcome_msg = "Connected to Server, Welcome!!!!!!!\n";

    char tmp[1024];

    int ii, kk, nn;

    int client_fd, clilen, rc;

 

    fd_set read_fds;

    WSADATA wsadata;

    SOCKET hservsock;

    SOCKADDR_IN client_addr, server_addr;

 

    if (argc != 2) {

        printf("usage : %s port\n", argv[0]);

        return(-1);

    }

 

    //The Windows Sockets WSAStartup function initiates use of WS2_32.DLL by a process.

    //The WSAStartup function must be the first Windows Sockets function called by an application or DLL. 

    //It allows an application or DLL to specify the version of Windows Sockets required and to retrieve details of the specific Windows Sockets implementation. 

    //The application or DLL can only issue further Windows Sockets functions after a successfully calling

    if(WSAStartup(MAKEWORD(2,2), &wsadata) != 0)

    {

        printf("Load Winsock 2.2 DLL Error\n");

        return(-9);

    }

 

    printf(">>>>>1. wsastartup succ!!(%d)(%d)\n", GetDate(), GetTime());

 

    hservsock=socket(PF_INET, SOCK_STREAM, 0);

    if(hservsock==INVALID_SOCKET)

    {

        printf("socket() error\n");

        return(-8);

    }

    printf(">>>>>2. socket succ!!(%d)(%d)\n", GetDate(), GetTime());

 

    bzero((char *)&server_addr, sizeof(server_addr));

    server_addr.sin_family = AF_INET;

    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    server_addr.sin_port = htons(atoi(argv[1]));

 

    if (bind(hservsock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {

        printf("server: can't bind local address.\n");

        return(-3);

    }

    printf(">>>>>3. bind succ!!(%d)(%d)\n", GetDate(), GetTime());

 

    listen(hservsock, 5); /* backlog = 5 */

    printf(">>>>>4. listen succ!!(%d)(%d)\n", GetDate(), GetTime());

 

    maxfdp1 = hservsock + 1;

 

    printf(">>>>>5. main ok!!!!!!!(%d)(%d)\n", GetDate(), GetTime());

    printf(">>>>>5. main ok!!!!!!!(%d)(%d)\n", GetDate(), GetTime());

    printf(">>>>>5. main ok!!!!!!!(%d)(%d)\n", GetDate(), GetTime());

 

    while (1) 

    {

        //initialization with all user(send), server(receive)

        FD_ZERO(&read_fds);

 

        //FD_SET은 관찰을 할 소켓들을 등록하는 변수입니다. 

        //소켓이 새로 만들어지고 select()함수를 통해 관찰을 하고 싶다면 fd_set변수에 소켓을 등록해야 합니다.

 

        //set register reference value with all user(send), server(receive)

        FD_SET(hservsock, &read_fds);

        for (ii=0; ii < g_num_chat; ii++)

        {

            FD_SET(client_s[ii], &read_fds);

        }

 

        //maxfdp1 variavle values re-calculation

        maxfdp1 = getmax(hservsock) + 1;

 

        /*wait & response, all client & server */

        /*wait & response, all client & server */

        /*wait & response, all client & server */

        /*wait & response, all client & server */

        if (select(maxfdp1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) 

        {

            printf("server: select error.\n");

            break;

        }

 

        //1. SELECT call and search change socket-filediscriptor

        //2. CHANGED socket-filediscriptor, find socket-filediscriptor, send, recv, accept function call

        //3. FD_ISSET(hservsock, &read_fds) is accept function calling

        //4. FD_ISSET(client_s[ii], &read_fds) is recv, send function calling

        if (FD_ISSET(hservsock, &read_fds)) 

        {

            //관찰의 대상은 server socket도 대상이 됩니다. 

            //기존에 존재하는 클라이언트가 아닌 새로운 클라이언트의 접속요청을 받앗을때에 해당됩니다.

 

            //select target is two groups

            //1. server socket

            //2. client socket(when multi, loop is needed)

 

            //1 user connected with server

            clilen = sizeof(client_addr);

            client_fd = accept(hservsock, (struct sockaddr *)&client_addr, &clilen);

            if (client_fd == -1) 

            {

                printf("server: accept error\n");

                break;

            }

            client_s[g_num_chat] = client_fd;

            g_num_chat++;

 

            printf("1. server: accept ok.cient fd[%d],all user cnt[%d]-------------------------\n", 

                      client_fd, g_num_chat);

    printf("1. server: accept ok.cient fd[%d],all user cnt[%d]-------------------------\n", 

                      client_fd, g_num_chat);

    printf("1. server: accept ok.cient fd[%d],all user cnt[%d]-------------------------\n", 

                      client_fd, g_num_chat);

 

            /*welcome message*/

            printf("2. server: send [welcome message] ok.--------------------------------------\n");

            send(client_fd, welcome_msg, strlen(welcome_msg), 0);

 

            if (getdottedipaddr(client_fd, &client_addr) > -1)

                printf("3. %d number additional(IP: %s)\n", g_num_chat, inet_ntoa(client_addr.sin_addr));

            else

                printf("3. %d number additional\n", g_num_chat);

        }

 

        /*ABOUT SERVER CONNECTED, g_num_chat수에 대해 RECEIVE 메세지가 있는지 ALL 조사해서,

        g_num_chat수만큼 다시 해당메세지를 ALL SENDING.*/

        for (ii=0; ii<g_num_chat; ii++) 

        {

            //client_s[ii]에 read_fds의 값이 설정되어 있으면 0이 아닙니다.

            if (FD_ISSET(client_s[ii], &read_fds)) 

            {

                printf("4. server: recv ok,client_s[%.5d][%d].------------------------------------------\n", 

                          ii+1, client_s[ii]);

                if ((nn = recv(client_s[ii], rline, MAXLINE, 0)) <= 0) 

                {

                    removeclient(ii); /* abrupt exit *//* abrupt exit *//* abrupt exit *//* abrupt exit */

                    continue;

                }

                rline[nn] = 0x00;

 

                if (strstr(rline, escapechar) != NULL) 

                {

                    removeclient(ii); /* abrupt exit *//* abrupt exit *//* abrupt exit *//* abrupt exit *//* abrupt exit */

                    continue;

                }

 

                //according to recv msg, logic execute

                //according to recv msg, logic execute

                //according to recv msg, logic execute

                if(strstr(rline, "GOOGLE") != NULL) //unique user response

                {

                    rc = pushcall();

                    if(rc)

                    {

                        //ERROR

                    }

                    memset(send_calc_msg,0x00,sizeof(send_calc_msg));

                    strcpy(send_calc_msg, "google pushcall succ!!\n");

 

                    send(client_s[ii], send_calc_msg, strlen(send_calc_msg), 0);

                }

                if(strstr(rline, "help") != NULL) //unique user response

                {

                    memset(tmp,0x00,sizeof(tmp));

                    strcat(tmp, "1. GOOGLE\n");

strcat(tmp, "2. calc>>\n");

strcat(tmp, "3. msg>>\n");

 

                    send(client_s[ii], tmp, strlen(tmp), 0);

                }

                else if(strstr(rline, "calc>>") != NULL) //all user response

                {

                    memset(send_calc_msg,0x00,sizeof(send_calc_msg));

                    memset(input,0x00,sizeof(input));

                    sprintf(input, "%s", strstr(rline, "calc>>") + strlen("calc>>"));

                    rc = calculation_socket(send_calc_msg);

                    if(rc)

                    {

                        //ERROR

                    }

 

                    for (kk=0; kk<g_num_chat; kk++)

                    {

                        printf("5. server: send ok,client_s[%.5d][%d]-------------------------------------------\n", kk+1, client_s[kk]);

                        if(client_s[kk] == client_s[ii])

                        {

                            send(client_s[kk], send_calc_msg, strlen(send_calc_msg), 0);

                        }

                        else

                        {

                            memset(tmp,0x00,sizeof(tmp));

                            memcpy(tmp, rline, nn);

                            strcat(tmp, "other user request & response:");

                            strcat(tmp, send_calc_msg);

                            send(client_s[kk], tmp, strlen(tmp), 0);

                        }

                    }

                }

                else if(strstr(rline, "msg>>") != NULL) //all user response

                {

                    memset(tmp,0x00,sizeof(tmp));

                    sprintf(tmp, "%s", strstr(rline, "msg>>") + strlen("msg>>"));

 

                    for (kk=0; kk<g_num_chat; kk++)

                    {

                        printf("5. server: send ok,client_s[%.5d][%d]-------------------------------------------\n", kk+1, client_s[kk]);

                        if(client_s[kk] == client_s[ii])

                        {

                            send(client_s[kk], tmp, strlen(tmp), 0);

                        }

                        else

                        {

                            send(client_s[kk], tmp, strlen(tmp), 0);

                        }

                    }

                }

 

                if (getdottedipaddr(client_fd, &client_addr) > -1)

                {

                    printf("6. IP:(%s),message:%s", inet_ntoa(client_addr.sin_addr), rline);

                }

                else

                {

                    printf("6. message:%s", rline);

                }

            }

        }

    } /* while */

 

    //The WSACleanup function terminates use of the Winsock 2 DLL (Ws2_32.dll).

    //The WSACleanup function terminates use of the Winsock 2 DLL (Ws2_32.dll).

    //The WSACleanup function terminates use of the Winsock 2 DLL (Ws2_32.dll).

    rc = WSACleanup();

    if(rc == WSANOTINITIALISED)

    {

        printf(">>error::A successful WSAStartup call must occur before using this function.\n");

    }

    else if(rc == WSAENETDOWN)

    {

        printf(">>error::The network subsystem has failed.\n");

    }

    else if(rc == WSAEINPROGRESS)

    {

        printf(">>error::A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.\n");

    }

    closesocket(hservsock);

}

 

void removeclient(int indx) 

{

    struct sockaddr_in client_addr;

 

    if (getdottedipaddr(client_s[indx], &client_addr) > -1)

    {

        printf("\nserver>>removeclient>>1 number expired!!(IP: %s).", inet_ntoa(client_addr.sin_addr));

    }

    else

    {

        printf("\nserver>>removeclient>>1 number expired!!.");

    }

 

    closesocket(client_s[indx]);

 

    if (indx != g_num_chat-1)

    {

        client_s[indx] = client_s[g_num_chat-1];

    }

 

    g_num_chat--;

    printf("\nserver>>removeclient>>now number = %d\n", g_num_chat);

}

 

int getmax(int k) 

{

    int max = k;

    int r;

 

    for (r=0; r < g_num_chat; r++)

    {

        if (client_s[r] > max) max = client_s[r];

    }

    return max;

}

 

int getdottedipaddr(int sd, struct sockaddr_in *addr) 

{

    struct sockaddr_in client_addr;

    int len, r;

 

    len = sizeof(client_addr);

    if ((r = getpeername(sd, (struct sockaddr *)&client_addr, &len)) == 0)

    {

        *addr = client_addr;

    }

    return r;

}

 

+ Recent posts