리눅스에서 파티션 FAT32 로 포맷하기

리눅스/OS 일반|2021. 3. 10. 09:10
반응형

파티션은 fdisk 로 생성한 다음 아래와 같은 형식으로 FAT32로 포맷할 수 있습니다.

(예: sdc 장치의 1번 파티션을 FAT32로 포맷)

 

# mkfs.vfat -F 32 /dev/sdc1

 

 

반응형

댓글()

c언어 소켓 통신 예제 (멀티 스레드, 멀티 프로세스)

프로그래밍/C, C++|2021. 3. 2. 15:24
반응형

멀티 스레드와 멀티 프로세스의 차이점을 설명한 글입니다.

요약하자면, 가장 큰 차이는 멀티스레드 방식은 공유 메모리를 갖고, 멀티프로세스 방식은 별도 메모리를 갖는듯..

내용을 확인 하신 후 상황에 맞는 소켓을 작성 하시기 바랍니다.

https://you9010.tistory.com/136

 

예제는 해외 사이트에서 가져왔으나, client 수 제한이 없거나 좀비프로세스 발생을 원치 않는다면 아래 URL 에서도 깔끔한 소스를 보실 수 있습니다.

https://velog.io/@jyongk/Multi-Process-Server-Multi-Thread-Server

 

 

멀티 스레드 방식

socket_server.c

 

#include <stdio.h>

#include <stdlib.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <string.h>

#include <arpa/inet.h>

#include <fcntl.h> // for open

#include <unistd.h> // for close

#include <pthread.h>

 

char client_message[2000];

char buffer[1024];

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

 

void * socketThread(void *arg)

{

  int newSocket = *((int *)arg);

  recv(newSocket , client_message , 2000 , 0);

 

  // Send message to the client socket 

  pthread_mutex_lock(&lock);

  char *message = malloc(sizeof(client_message)+20);

  strcpy(message,"Hello Client : ");

  strcat(message,client_message);

  strcat(message,"\n");

  strcpy(buffer,message);

  free(message);

  pthread_mutex_unlock(&lock);

  sleep(1);

  send(newSocket,buffer,13,0);

  printf("Exit socketThread \n");

  close(newSocket);

  pthread_exit(NULL);

}

 

int main(){

  int serverSocket, newSocket;

  struct sockaddr_in serverAddr;

  struct sockaddr_storage serverStorage;

  socklen_t addr_size;

 

  //Create the socket. 

  serverSocket = socket(PF_INET, SOCK_STREAM, 0);

 

  // Configure settings of the server address struct

  // Address family = Internet 

  serverAddr.sin_family = AF_INET;

 

  //Set port number, using htons function to use proper byte order 

  serverAddr.sin_port = htons(7799);

 

  //Set IP address to localhost 

  serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

 

 

  //Set all bits of the padding field to 0 

  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

 

  //Bind the address struct to the socket 

  bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

 

  //Listen on the socket, with 40 max connection requests queued 

  if(listen(serverSocket,50)==0)

    printf("Listening\n");

  else

    printf("Error\n");

    pthread_t tid[60];

    int i = 0;

    while(1)

    {

        //Accept call creates a new socket for the incoming connection

        addr_size = sizeof serverStorage;

        newSocket = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size);

 

        //for each client request creates a thread and assign the client request to it to process

       //so the main thread can entertain next request

        if( pthread_create(&tid[i++], NULL, socketThread, &newSocket) != 0 )

           printf("Failed to create thread\n");

 

        if( i >= 50)

        {

          i = 0;

          while(i < 50)

          {

            pthread_join(tid[i++],NULL);

          }

          i = 0;

        }

    }

  return 0;

}

 

멀티프로세스 방식

socket_server.c

 

#include <stdio.h>

#include <stdlib.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <string.h>

#include <arpa/inet.h>

#include <fcntl.h> // for open

#include <unistd.h> // for close

#include <sys/types.h>

#include <pthread.h>

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

 

void  socketThread(int clientSocket)

{

 

  char client_message[2000];

  char buffer[1024];

 

  int newSocket = clientSocket;

 

  recv(newSocket , client_message , 2000 , 0);

 

  // Send message to the client socket

  pthread_mutex_lock(&lock);

  char *message = malloc(sizeof(client_message)+20);

  strcpy(message,"Hello Client : ");

  strcat(message,client_message);

  strcat(message,"\n");

  strcpy(buffer,message);

  free(message);

  pthread_mutex_unlock(&lock);

  sleep(1);

  send(newSocket,buffer,13,0);

  printf("Exit socketThread \n");

  close(newSocket);

  }

 

 

 

int main(){

  int serverSocket, newSocket;

  struct sockaddr_in serverAddr;

  struct sockaddr_storage serverStorage;

  socklen_t addr_size;

  pid_t pid[50];

  //Create the socket.

  serverSocket = socket(PF_INET, SOCK_STREAM, 0);

 

  // Configure settings of the server address struct

  // Address family = Internet

  serverAddr.sin_family = AF_INET;

 

  //Set port number, using htons function to use proper byte order

  serverAddr.sin_port = htons(7799);

 

  //Set IP address to localhost

  serverAddr.sin_addr.s_addr = inet_addr("0.0.0.0");

  //Set all bits of the padding field to 0

  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

 

  //Bind the address struct to the socket

  bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

 

  //Listen on the socket, with 50 max connection requests queued

  if(listen(serverSocket,50)==0)

    printf("Listening\n");

  else

    printf("Error\n");

    int i = 0;

while(1)

    {

        /* Accept call creates a new socket for the incoming connection */

        addr_size = sizeof serverStorage;

        newSocket = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size);

        int pid_c = 0;

 

      if ((pid_c = fork())==0)

        {

          socketThread(newSocket);

        }

        else

        {

          pid[i++] = pid_c;

          if( i >= 49)

           {

             i = 0;

             while(i < 50)

                waitpid(pid[i++], NULL, 0);

             i = 0;

           }

        }

    }

  return 0;

}


클라이언트 소켓 파일

socket_client.c

 

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <string.h>

#include <arpa/inet.h>

#include <stdlib.h>

#include <fcntl.h> // for open

#include <unistd.h> // for close

#include<pthread.h>

 

void * cientThread(void *arg)

{

  printf("In thread\n");

  char message[1000];

  char buffer[1024];

  int clientSocket;

  struct sockaddr_in serverAddr;

  socklen_t addr_size;

 

  // Create the socket. 

  clientSocket = socket(PF_INET, SOCK_STREAM, 0);

 

  //Configure settings of the server address

 // Address family is Internet 

  serverAddr.sin_family = AF_INET;

 

  //Set port number, using htons function 

  serverAddr.sin_port = htons(7799);

 

 //Set IP address to localhost

  serverAddr.sin_addr.s_addr = inet_addr("localhost");

  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

 

    //Connect the socket to the server using the address

    addr_size = sizeof serverAddr;

    connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);

    strcpy(message,"Hello");

 

   if( send(clientSocket , message , strlen(message) , 0) < 0)

    {

            printf("Send failed\n");

    }

 

    //Read the message from the server into the buffer

    if(recv(clientSocket, buffer, 1024, 0) < 0)

    {

       printf("Receive failed\n");

    }

    //Print the received message

    printf("Data received: %s\n",buffer);

    close(clientSocket);

    pthread_exit(NULL);

}

int main(){

  int i = 0;

  pthread_t tid[51];

  while(i< 50)

  {

    if( pthread_create(&tid[i], NULL, cientThread, NULL) != 0 )

           printf("Failed to create thread\n");

    i++;

  }

  sleep(20);

  i = 0;

  while(i< 50)

  {

     pthread_join(tid[i++],NULL);

     printf("%d:\n",i);

  }

  return 0;

} 

 

 

 

[출처] https://dzone.com/articles/parallel-tcpip-socket-server-with-multi-threading

[수정] 출처의 예제에 오타가 있어서 바로 실행하면 에러가 발생합니다. 소스를 보완하여 작성하였습니다.

반응형

댓글()

c언어 파일 이벤트 감시 (inotify)

프로그래밍/C, C++|2021. 2. 24. 11:56
반응형

파일이 생성, 변경, 삭제 되었을때 실시간으로 감지하여 특정 소스를 처리할 수 있습니다.

아래 소스를 백그라운드로 돌릴 경우 메세지 출력이 되지 않으나 동작은 되는것을 확인하였습니다.

파일 이벤트 종류는 아래 세가지 외에 더 있으므로 상세 감지가 필요하신 분은 기타 문서를 참고하시기 바랍니다.


#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/inotify.h>

#include <unistd.h>


#define EVENT_SIZE  (sizeof(struct inotify_event))

#define BUF_LEN     (1024 * (EVENT_SIZE + 16))


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

    int length, i = 0;

    int fd;

    int wd;

    char buffer[BUF_LEN];


    fd = inotify_init();


    if (fd < 0) {

        perror("inotify_init");

    }


    wd = inotify_add_watch(fd, ".", // 현재 경로를 나타내며, 특정파일로 지정 가능합니다.

        IN_MODIFY | IN_CREATE | IN_DELETE);

    length = read(fd, buffer, BUF_LEN);


    if (length < 0) {

        perror("read");

    }


    while (i < length) {

        struct inotify_event *event =

            (struct inotify_event *) &buffer[i];

        if (event->len) {

            if (event->mask & IN_CREATE) {

                printf("The file %s was created.\n", event->name);

            } else if (event->mask & IN_DELETE) {

                printf("The file %s was deleted.\n", event->name);

            } else if (event->mask & IN_MODIFY) {

                printf("The file %s was modified.\n", event->name);

            }

        }

        i += EVENT_SIZE + event->len;

    }


    (void) inotify_rm_watch(fd, wd);

    (void) close(fd);


    return 0; 

}




[출처] https://stackoverflow.com/questions/13351172/inotify-file-in-c


반응형

댓글()

c언어 마지막줄 문자열 중복 출력하지 않기

프로그래밍/C, C++|2021. 2. 24. 10:41
반응형

feof() 함수를 이용해 파일내용을 출력할 경우 파일의 맨 마지막줄 문자열은 중복 출력되는 경우가 있습니다. 이럴때 아래와 같은 코드를 추가하여 중복 출력을 방지할 수 있습니다.


while (feof(fb) == 0) {   // 파일내용이 끝날때까지 반복

    if(fgets(str, 100, fb) == NULL) break;  // 괄호 내용은 순서대로 '문자열, 사이즈, FILE*'

    ... 생략 ...

}




반응형

댓글()

c언어 string 문자형을 int 형으로 변환하기

프로그래밍/C, C++|2021. 2. 24. 10:15
반응형

str 문자열에 숫자만 있을 경우 아래와 같은 코드를 사용하여 int 를 입력할 곳에 넣을 수 있습니다.

 

(int) strtol(str, (char **)NULL, 10)

 

 

[출처] https://stackoverflow.com/questions/7021725/how-to-convert-a-string-to-integer-in-c

반응형

댓글()

c언어 변수 내용 비우기 (문자열 초기화)

프로그래밍/C, C++|2021. 2. 24. 10:05
반응형

시스템에 따라 아래 코드가 정상 컴파일 되거나 안되는 경우가 있습니다.


sprintf(str, ""); // str 변수 내용 비우기


이러한 코드를 가진 소스가 아래와 같이 컴파일 할 때 에러를 출력한다면


# gcc sysdocu.c -o sysdocu

sysdocu.c:72:22: warning: zero-length gnu_printf format string [-Wformat-zero-length]

         sprintf(str, "");

                      ^~


아래와 같이 변경하여 사용이 가능합니다.


sprintf(str, "%s", "");





반응형

댓글()

c언어 파일 내용 출력하기

프로그래밍/C, C++|2021. 2. 19. 08:41
반응형

# cat test.txt

aaa

bbb

ccc


# vi test.c


#pragma warning(disable :4996)

#define MAX_LEN 100

#include <stdio.h>


int main()

{

    FILE* fs;

    fs = fopen("test.txt", "r");

    while (feof(fs) == 0) {

        char str[MAX_LEN];

        fgets(str, MAX_LEN, fs);

        printf("%s", str);

    }

}


# gcc test.c -o test


# ./test

aaa

bbb

ccc



[소스 출처] https://jeckl.tistory.com/entry/C%EC%96%B8%EC%96%B4-21%EA%B0%95-%ED%8C%8C%EC%9D%BC-%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%9D%BD%EA%B8%B0-fopen-fgets-fseek-feof-fclose

반응형

댓글()

c언어 문자열에서 숫자만 가져와서 출력하기

프로그래밍/C, C++|2021. 2. 18. 16:15
반응형

/* 문자와 숫자가 섞여있는 문자열이 주어지면 그 중 숫자만 추출하여 그 순서대로 자연수를 만듭니다. 만들어진 자연수와 그 자연수의 약수 개수를 출력합니다. 만약 "fsaknf0012lsaf"에서 숫자만 추출하면 0,0,1,2고 이것을 자연수로 만들면 12가 됩니다. 즉 첫 자리 0은 자연수화 할 때 무시합니다. 출력은 12를 출력하고, 다음 줄에 12의 약수의 개수를 출력하면 됩니다. 추출하여 만들어지는 자연수는 100,000,000을 넘지 않습니다. */ 


# include <stdio.h> 

int main(){ 

    char a[100]; 

    int res = 0, cnt = 0, i; 

    scanf("%s", &a); 

    for(i = 0; a[i]!='\0'; i++) { 

        if(a[i]>=48 && a[i]<=57) { 

            res = res * 10 + (a[i]-48); 

        }

    } 

    printf("자연수 : %d\n",res); 


    for(i = 1; i<=res; i++) { 

        if(res%i ==0) 

            cnt++; 

    } 

    printf("약수의 개수 : %d\n",cnt); return 0; }


출처: https://asthtls.tistory.com/53 [포장빵의 IT]

반응형

댓글()

Ubuntu 18.04 텔레그램에서 한글 사용하기

리눅스/OS 일반|2021. 2. 18. 08:42
반응형

우분투 기본 iBus 한글입력기 말고 fcitx 입력기를 사용하면 쉽게 해결이 됩니다.


1. 한글 입력 패키지 설치

# apt -y install fcitx-hangul fcitx-config-gtk


2. 설정

프로그램 표시 > 언어 지원 > '언어'탭 하단 키보드 입력기를 'fcitx' 로 변경한 후


로그오프, 로그인 을 거치면 텔레그램에서 한글 사용이 가능해집니다.



반응형

댓글()

CentOS 7 에서 모니터링 도구 Zabbix 5.2.3 설치 및 호스트 추가하기

리눅스/OS 일반|2021. 2. 17. 15:04
반응형

OS 는 CentOS 7 이고 APM 소스 설치 전제하에 진행 하였습니다.

참고로 Zabbix 5.2.3 버전은 PHP 7.2 이상을 필요로 합니다.

 

[ Zabbix 서버 ]

 

1. 다운로드

 

# cd /usr/local/src

# wget http://cdn.zabbix.com/zabbix/sources/stable/5.2/zabbix-5.2.3.tar.gz

# tar zxvf zabbix-5.2.3.tar.gz

# cd zabbix-5.2.3

# ./configure --prefix=/usr/local/zabbix/ --enable-server --enable-agent --with-mysql=/usr/local/mysql/bin/mysql_config --enable-ipv6 --with-net-snmp=/usr/bin/net-snmp-config --with-libcurl

# make

# make install

 

 

2. 데이터 베이스 설정

 

# mysql -p

(root 패스워드 입력후 엔터)

mysql> create database zabbix character set utf8 collate utf8_bin;

mysql> grant all privileges on zabbix.* to zabbix@localhost identified by '12345678'; // 계정은 알맞게 입력

mysql> flush privileges;

 

# cd /usr/local/src/zabbix-5.2.3/database/mysql

# mysql -p zabbix < schema.sql

# mysql -p zabbix < images.sql

# mysql -p zabbix < data.sql

 

 

3. 계정 생성

 

(안되어 있을 경우)

# groupadd --system zabbix

# useradd --system -g zabbix -d /usr/lib/zabbix -s /sbin/nologin -c "Zabbix Monitoring System" zabbix

 

 

4. 웹소스 복사 및 초기 구성

 

# mkdir -p /home/zabbix/public_html

# cp -arp /usr/local/src/zabbix-5.2.3/ui/* /home/zabbix/public_html

 

웹서버에 사이트를 추가로 구성 합니다.

 

# vi /usr/local/apache/conf/extra/httpd-vhost.conf

 

<VirtualHost *:80>

    DocumentRoot "/home/zabbix/public_html"

    ServerName sysdocu.tistory.com

    ErrorLog "logs/sysdocu.tistory.com-error_log"

    CustomLog "logs/sysdocu.tistory.com-access_log" combined

</VirtualHost> 

 

# /usr/local/apache/bin/apachectl restart

 

관리 UI 에서 DB 접근이 가능하도록 아래 파일을 열어 옵션을 수정 합니다.

 

# vi /usr/local/zabbix/etc/zabbix_server.conf

 

DBHost=localhost

DBName=zabbix

DBUser=zabbix

DBPassword=12345678

DBSocket=/tmp/mysql.sock

 

파일 저장 후 zabbix 를 구동합니다.

 

# /usr/local/zabbix/sbin/zabbix_server -c /usr/local/zabbix/etc/zabbix_server.conf

 

구동시 아래와 같은 에러가 출력될 경우

/usr/local/zabbix/sbin/zabbix_server: error while loading shared libraries: libmysqlclient.so.20: cannot open shared object file: No such file or directory

 

해결 방법입니다.

# echo "/usr/local/mysql/lib" >> /etc/ld.so.conf    // 구동전 /usr/local/mysql/lib 디렉토리 내에 libmysqlclient.so.20 파일을 확인합니다.

# ldconfig

# /usr/local/zabbix/sbin/zabbix_server -c /usr/local/zabbix/etc/zabbix_server.conf

 

 

웹브라우저를 통해 zabbix 관리 페이지에 접속합니다.

 

php 설정 상태에 따라 진행이 가능하며, 진행 완료 페이지에서 conf 가 적용되지 않을 경우 제공하는 설정파일을 다운로드 받아 아래 파일로 저장합니다.

 

/home/zabbix/public_html/zabbix.conf.php

 

이제 다시 사이트에 접속 하면 관리 UI 로 로그인이 가능합니다.

http://sysdocu.tistory.com

 

초기 패스워드 : Admin / zabbix

 

 

[ Host 추가 ]

 

모니터링 대상 서버를 관리 목록에 추가 합니다.

외부에서 대상 서버를 모니터링 하기 위해 서버 내에 agent 를 설치해야 합니다.

 

1. 패키지 설치

 

(모니터링 대상 서버에서)

# wget http://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-release-4.0-2.el7.noarch.rpm

# wget http://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.28-1.el7.x86_64.rpm

# rpm -Uvh zabbix-release-4.0-2.el7.noarch.rpm

# rpm -Uvh zabbix-agent-4.0.28-1.el7.x86_64.rpm

 

 

2. 설정 및 실행

 

# vi /etc/zabbix/zabbix_agentd.conf

 

Server=10.10.10.10 // 관리자 서버 IP 입력
Hostname=20.20.20.20 // 호스트 서버 IP 입력

 

# systemctl enable zabbix-agent

# systemctl start zabbix-agent

 

브라우저를 통해 관리페이지에 접속 합니다.

 

http://sysdocu.tistory.com

 

설정 > 호스트 그룹 > '호스트 그룹 작성' 클릭

- 그룹 이름 : 'Managed Group' 입력

 

설정 > 템플릿 > '템플릿 작성' 클릭

- 템플릿 이름 : 'Managed Template' 입력

- 표시명 : 'Managed Template' 입력

- 그룹 : 'Managed Group' 선택

 

설정 > 호스트 > '호스트 작성' 클릭

- 호스트명 : 'First Server' 입력

- 표시명 : 'First Server' 입력

- 그룹 : 'Managed Group' 선택

- Interfaces : '추가' 버튼 클릭 > '에이전트' 선택 > 모니터링 대상 서버 (호스트 서버) IP 와 포트 10050) 입력

- [템플릿] 탭의 'Link new templates' 에서 'Managed Template' 선택

 

 

'추가' 버튼을 누르고 리스트로 나오면 시간이 조금 걸려서 '상태'값 [ZBX] 부분이 '녹색'으로 활성화 됩니다.

 

 

 

 

반응형

댓글()

c언어 소켓 close 할때 TIME_WAIT 상태로 남아 있는 경우

프로그래밍/C, C++|2021. 2. 16. 08:34
반응형

TIME_WAIT는 소켓 close를 호출하는 쪽에서 설정되는 소켓의 상태이다.

netstat을 사용하여 각 소켓의 상태를 확인할 수 있다.

짧은 작업을 위한 소켓인 경우, Server에서 close를 호출하는 경우가 생기는데, 이 때 부하가 많을수록 TIME_WAIT 상태인 소켓이 많아져 Client에서 Server로 접속을 못하는 경우가 생긴다.

 

다음과 같이 강제적으로 TIME_WAIT상태를 거치지 않고 소켓을 종료할 수 있다.

(기본적으로 TIME_WAIT는 소켓의 필수 상태이니 테스트 필수!!)

 

struct linger ling;

ling.l_onoff = 1;

ling.l_linger = 0;

shutdown(sockfd, SD_BOTH);

setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));

#define WIN32

sockclose(fd);

#else

close(fd);

#endif

 

apache proxy loadbalancer를 사용하는 경우, native 데몬(혹은 tomcat등의 proxy와 연결되는 daemon)과 apache proxy사이의 소켓은 즉시 종료 되나, 클라이언트와 apache간의 소켓은 apache의 KeepAlive설정에 따라 달라진다. KeepAlive를 On으로 설정하는 경우, 클라이언트의 소켓이 close를 먼저 하게 되므로 서버쪽에서는 소켓이 남지 않고, Off로 설정하는 경우, 서버에서 먼저 close를 호출하므로 서버쪽에 소켓이 남게 된다. (남게 되는 소켓은 전부 TIME_WAIT 상태의 소켓을 뜻함)

 

 

출처: https://indra17.tistory.com/entry/소켓-Close시-TIMEWAIT-대기시간-설정C언어 [피로에 살고 피로에 죽자]

 

---------------------------

[ 실제 적용 소스 ]

 

shutdown(client_fd, SHUT_RDWR);
struct linger ling;
ling.l_onoff = 1;
ling.l_linger = 0;
setsockopt(server_fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
close(client_fd);

 

반응형

댓글()