https://ropiens.tistory.com/41?category=828450 

 

ROS2 foxy 튜토리얼3 - ROS2 노드(node) 이해하기

그동안은 ROS2의 학습용 패키지인 turtlesim 패키지만을 돌려봤습니다. 이번 차 부터는 그 것들이 어떻게 돌아가는 지 내부를 알아보면서 다시 한 번 학습을 해 보겠습니다. 오늘은 노드(node)에 대해

ropiens.tistory.com

 

이 블로그를 보고 따라해보다가 뒷부분을 이어서 써본다.

 

 

Topic이란?

  • node가 메시지를 교환하는 버스 역할
  • 여러 topic에 데이터를 게시 및 구독할 수 있음.
  • 데이터가 node 간에 이동하는 주요 방법 중 하나

 

 

실습

1. 설정

터미널 2개를 열고 다음과 같은 명령어를 실행한다.

(참고 : ros2 run <package_name> <executable_name>)

- 터미널 1

ros2 run turtlesim turtlesim_node

- 터미널 2

ros2 run turtlesim turtle_teleop_key

 

2. rqt_graph

또 다른 터미널을 열고 rqt_graph를 실행한다.

- 터미널 3

rqt_graph

 

 

위와 같은 창을 볼 수 있다.

이 그래프는 방금 실행시킨 /turtlesim 노드와 /teleop_turtle 노드가 topic에 대해 서로 통신하는 모습을 보여준다.

/teleop_turtle node는 키 데이터를 /turtle1/cmd_vel topic에 pub하고 /turtlesim node는 그 topic을 sub해서 데이터를 받아온다.

 

3. ros2 topic list

새로운 터미널에서 다음과 같은 명령어를 입력해 현재 활성화된 topic list를 확인한다.

- 터미널 4

ros2 topic list

그러면 다음과 같은 list가 반환된다.

/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
더보기

참고로 $ ros2 node info /turtlesim 을 입력했을 때도 

Subscribers와 Publishers에 같은 topic이 출력된다.

 

4. ros2 topic echo

pub되는 data를 확인하려면 다음과 같은 명령어를 사용한다.

- ros2 topic echo <topic_name>

위 그림의 /turtle1/cmd_vel topic을 확인해볼 것이다.

- 터미널 4

ros2 topic echo /turtle1/cmd_vel

 

터미널 4가 실행되는 채로 놔두고 터미널 2를 클릭해서 활성화 시킨 후 turtle을 방향키로 조작해본다.

그러면 터미널 4에 다음과 같이 출력될 것이다.

 

다시 rqt_graph로 가서 Debug의 체크를 해제한 후 왼쪽 상단의 새로고침을 누른다.

그러면 창이 아래와 같이 바뀌는데 /turtle1/cmd_vel topic을 다른 node가 sub하고 있는 것을 알 수 있다.

아래의 /_ros2cil_17865 가 터미널 4에서 실행한 노드이다.

 

 

5. ros2 topic info

topic의 정보를 보고 싶다면 다음과 같은 명령어를 사용하면 된다.

- ros2 topic info <topic_name>

- 터미널 5

ros2 topic info /turtle1/cmd_vel

그러면 아래와 같이 Topic Type과 Publisher, Subscription count가 출력된다.

 

6. ros2 interface show

ros2 topic list -t 라는 명령어를 사용하면 현재 topic의 message type을 알려준다.

- 터미널 5

ros2 topic list -t

아래의 사진에서 확인할 수 있듯이 /turtle1/cmd_vel은 geometry_msgs/msg/Twist를 사용한다.

이것은 geometry_msgs 안에 Twist라고 불리는 msg가 있다는 걸 의미한다.

 

이 메시지 구조에 대해 자세히 알고 싶다면 다음과 같은 명령어를 이용한다.

- 터미널 5

ros2 interface show geometry_msgs/msg/Twist

다음과 같이 출력된다.

4번째 과정에서 확인한 것과 같은 형식으로 구성되어 있는 것을 확인할 수 있다.

 

 

7. ros2 topic pub

6번째 과정에서 메시지 구조를 알 수 있었다.

메시지 형식만 맞춘다면 터미널에서 직접 데이터를 게시하는 것이 가능하다.

ros2 topic pub <topic_name> <msg_type> <args> 꼴로 작성하면 된다.

 

-터미널 5

ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"

거북이가 호를 그리는 것을 확인할 수 있다.

 

여기서 --once 는 하나의 메시지를 게시한 후 종료하는 옵션이다. 만약 이 옵션을 추가하지 않는다면 ^C를 누르기 전까지 계속해서 거북이가 빙글빙글 돈다.

 

ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"

이 명령어는 --once를 제거한 후 --rate 1 옵션을 추가한 명령어인데 1Hz로 메시지를 게시하는 것이다.

 

 

8. ros2 topic hz

아래와 같은 명령어를 사용해서 topic이 게시되는 hz를 볼 수 있다.

ros2 topic hz <topic_name>

요약 : 클라우드 서버를 이용해서 로봇의 computing / storage resources 이상의 성능을 발휘할 수 있다.

 

1. INTRODUCTION

개발 현황

  • Davinci project
    • robot algorithm is implemented in the Map/Reduce
    • ROS is chosen as the messaging frame.
  • RoboEarth
    • search engine in the field of robots.
    • Rapyuta is an open source cloud frame based on the RoboEarth.
    • Linux containers for service security.
    • ROS nodes are running in the computing environment.
  • micROS-cloud
  • Vision API of Google Cloud Platform
  • NOOS

However, those cloud services are from different providers and their access interfaces are quite different, which causes significant difficulty for task integration.

 

 

CloudROS

  • The cloud provides computing and storing services in form of ROS nodes.
  • The cloud also converts the third-party web services to ROS compatible cloud services.
  • The cloud exposes its REST API to users and robots.

 

2. CLOUDROS FRAMEWORK

A. ROS

 

B. REST API

  • non-ROS interfaces are required to assist the dynamic ROS network establishing task.
  • The design style of a RESTful architecture
    1. The Web resource is the core of REST architecture.
    2. It realizes a loose coupling between the resource and view functions.
    3. The standart HTTP request methods are used to request the web service.
    4. It follows the C/S framework.
  • URI
    • A typical URI for computing service : http://server_ip:port/compute/<service>/<action>/<token>
      • server_ip:port : IP address of the cloud server and the port that the clod service manager continuously listens to.
      • compte : computing service is requested.
      • service : cloud computing services provided by the cloud robotics platform.
      • action : particular operation that controls status of the services.
      • token : unique security credentials.
    • A typical URI for storage service : http://server_ip:port/storage/<robotID>/<action>/<token>
      • storage : cloud storing service is requested.
      • robotID : unique ID of the robots.
      • action : operations on the cloud data sets, include "fetch" and "store".

C. Docker

  • Docker container technique is used as the computing environment for the cloud system to ensure services isolation and system security.
  • lighter and start-up speed is faseter.
  • It needs to install the ROS and deploy corresponding ROS packages and configure the command sets for managing service nodes.

D. Architecture of Cloud System

Robot-Cloud

  • All cloud service nodes can be executed in the dock container which is pre-installed with ROS environment.
  • Based on the non-ROS interface protocols(?REST API?), URI of the ROS master node can be transmitted to the cloud service manager and the cloud service nodes can connect and join the ROS network located at the local robot. 
  • robot and cloud have a common ROS master nodem the messages can be automatically transferred based on ROS topics.

Cloud-User

  • The user can access the public data stored in the cloud via the REST APIs.
  • The monitoring applications should also be developed as a ROS network.

 

E. Cloud Service Nodes Integration

 

3. CLOUDROS ENABLED MOBILE ROBOT PLATFORM

A. Mobile Robot Platform

B. Kinematic Model

~~ pass ~~

 

4. EXPERIMENT RESULTS

A. Computing Service Experiment

 

B. Storing Service Experiment

각 로봇은 각자의 저장소에 데이터를 저장한다. 그리고 각 로봇의 저장소마다 새로운 정보가 또다시 하나의 저장소에 업데이트 된다.  User는 하나의 저장소에 있는 정보를 사용한다.

2. 로봇 SW와 클라우드 컴퓨팅 기술의 연구 개발 동향

다양한 사례

  • DAvinCi 프로젝트
    • ROS를 클라우드와 연결하려는 대표적인 시도 
    • FastSLAM이라는 대표적인 지도 작성 로봇 알고리즘을 Hadoop 시스템 상의 Map/Reduce 작업으로 병렬화하고 ROS를 메세지 프레임워크로 이용하여 실행시간을 현저히 단축시킴으로써 클라우드 로보틱스의 장점을 입증함.
  • RoboEarth 프로젝트
    • EU의 7번째 프레임워크 프로젝트로 진행된 RoboEarth 프로젝트
    • 목표
      1. 로봇 시스템이 네트워크에 있는 정보 저장소와 연결되면 빠른 학습과 적응을 통해 복잡한 작업을 수행할 수 있음을 입증
      2. 이를 통해 설계 시에 계획하지 않았던 유용한 작업들도 클라우드 연결을 통해 자동으로 수행 가능함을 입증
    •  

컨테이너 개발 시대

  • 클라우드 컴퓨팅 업체들은 주어진 작업을 작게 세분화하고 컨테이너라는 단위로 패키징하여 관리함으로써 소비자가 원하는 서비스를 제공함.
  • 이 작업을 위해 구글에서 Kubernetes라는 컨테이너 관리 도구가 표준으로 자리잡음.
  • 구글에서는 Cloud Robotics ore을 발표하기도 함.

Limited Direct execution

가상화 기법을 구현하기 위해서는 아래와 같은 문제를 해결해야 한다.

  1. 성능저하 : 시스템에 과중한 오버헤드를 주지 않으면서 가상화를 구현해야 한다.
  2. 제어 문제 : CPU에 대한 통제를 유지하면서 프로세스를 효율적으로 실행해야 한다.

 

Problem 1 : Restricted Operation

Direct execution은 빠르게 실행된다는 장점이 있지만 프로세스가 특수한 종류의 연산(I/O 입출력, 자원 독점)을 수행하길 원한다면 문제가 발생할 수 있다.

 

따라서 User modeKernel mode를 사용한다.

  • User mode
    • User mode에서 실행되는 코드는 할 수 있는 일이 제한된다.
    • ex) 입출력 요청을 할 수 없도록 설정한 후 프로세스가 입출력 요청을 하면 프로세서가 예외를 발생시키고, 운영체제는 해당 프로세스를 제거한다.
    • 제한 작업의 실행을 허용하기 위하여 system call이 제공된다.
  • Kernel mode
    • 모든 특수한 명령어를 포함하여 원하는 모든 작업을 수행할 수 있다.

 

System Call

  1. trap
    1. 프로그램은 system call을 실행하기 위해 trap 명령어를 실행해야 한다.
    2. 커널 안으로 분기하는 동시에 특권 수준을 Kernel mode로 상향 조절한다.
    3. Kernel mode로 진입한 후 운영체제는 모든 명령어를 실행할 수 있고 이를 통하여 프로세스가 요청한 작업을 처리할 수 있다.
      • trap은 운영체제 코드의 어디를 실행할 지 알 수 없다. 호출한 프로세서는 분기할 주소를 명시할 수 없기 때문이다. (주소를 명시한다는 것은 커널 내부의 원하는 지점을 접근할 수 있다는 의미이므로 위험하다.)
      • 따라서 커널은 부팅 시에 trap table을 만들고 하드웨어에게 trap handler의 위치를 알려준다.
  2. return-from-trap
    1. 프로세스가 요청한 작업을 처리하면 운영체제는 return-from-trap 특수 명령어를 호출한다.
    2. 특권 수준을 User mode로 하향 조정하면서 호출한 사용자 프로그램으로 리턴한다.

 

 

 

.............................................

 

Problem 2 : Switching Between Processes

cooperative & non-cooperative

  • Cooperative
    • 프로세스가 CPU를 자발적으로 양보한다.
    • 비정상적인 행위(0으로 나누기, 접근할 수 없는 메모리에 접근)를 하면 운영체제에게 제어가 넘어간다. 
    • 만약 프로세스가 무한 루프에 빠져 시스템 콜을 호출할 수 없을 때에는 재부팅밖에 방법이 없다.
  • Non-Cooperative : OS Takes Control
    • timer interrupt를 이용한다.

 

Saving and Restoring Context 

두 번의 레지스터 저장/복원이 발생한다.

첫 번째는 타이머 인터럽트가 발생했을 때 일어난다. 실행 중인 프로세스의 사용자 레지스터가 하드웨어에 의해 암묵적으로 저장되고 저장 장소로 해당 프로세스의 커널 스택이 사용된다.

두 번째는 운영체제가 A에서 B로 전환하기로 결정했을 때 일어난다. 커널 레지스터는 운영체제에 의하여 해당 프로세스의 프로세스 구조체에 저장된다.

 

 

Worried About Concurrency?

system call을 처리하는 도중에 타이머 인터럽트가 발생한다면?

하나의 인터럽트를 처리하고 있을 때 다른 인터럽트가 발생한다면?

 

=> Lock 기법을 이용한 방법을 뒷 장에서 배운다. 

 

 

 


광운대학교 김태석 교수님 운영체제 수업과

[운영체제 : 아주 쉬운 세 가지 이야기] 책 참고

'21-2학기 > 운영체제' 카테고리의 다른 글

[Virtualizaton] 3. Process API  (0) 2022.01.04
[Virtualizaton] 2. Processes  (0) 2022.01.04

Process Creation

Parent process는 child process를 만든다. 이 형태는 tree 모양을 가지게 된다.

 

Child process의 resources, Execution, Address space은 다음과 같다.

  • Resource
    • OS gives
    • Pareent share
      1. all
      2. subset
      3. no
  • Execution
    • concurrently
    • Parent waits until child terminate
  • Address space
    • Child duplicates parent
    • Child has a new program loaded into it.

 

 

프로세스 생성은 다음과 같은 과정을 포함한다.

  • Create PCB within OS kernel
  • Allocate memory space
  • Load Binary program
  • Initialize the program

 

UNIX에서는 Process Creation을 위해 fork와 execve system call을 제공한다.

 

 

Process Termination

  • exit (정상 종료)
  • abort (강제 종료)

 

Process Creation & Termination

 

 

Process API

1. fork()

2. wait()

3. exec()

 

 


광운대학교 김태석 교수님 운영체제 수업과

[운영체제 : 아주 쉬운 세 가지 이야기] 책 참고

'21-2학기 > 운영체제' 카테고리의 다른 글

[Virtualizaton] 4. Limited Direct execution  (0) 2022.01.04
[Virtualizaton] 2. Processes  (0) 2022.01.04

Virtualization이란

시스템에 존재하는 하나의 자원을 각 프로그램에게 여러 개의 자원처럼 보이게 하는 것이다.

각 프로그램은 하나의 자원을 공유하고 있지만 각자의 자원이 있다는 환상을 갖게 된다.

Processes

프로세스의 개념

프로세스는 실행 중인 프로그램으로 정의한다. 프로그램은 디스크 상에 존재하며 실행을 위한 명령어와 정적 데이터의 묶음을 말한다.

사용자는 하나 이상의 프로그램을 동시에 실행시키기를 원하므로 운영체제는 적은 개수의 CPU 밖에 없더라도, 무한개에 가까운 CPU가 존재한다는 환상을 제공해야한다.

이러한 환상은 가상화를 통해 만들어진다. CPU 가상화는 저수준의 도구인 메커니즘과 고차원적인 지능인 정책으로 구성된다.

모든 현대 운영체제들은 시분할(time sharing) 기법을 사용해 가상화를 만들어낸다.

프로세스의 구성 요소를 이해하기 위해서는 하드웨어 상태(machine state)를 이해해야 한다.

메모리(Address space)와 레지스터는 프로세스의 하드웨어 상태에 포함된다.

메모리는 Code(Text), Data, Stack, Heap 으로 구성되어 있고 레지스터는 Program Counter, Stack Pointer 등으로 구성되어 있다.

프로세스 API

운영체제가 반드시 API로 제공해야 하는 기능은 다음과 같다.

  • 생성(Create) : 운영체제는 새로운 프로세스를 생성할 수 있는 방법을 제공해야 한다. 쉘에 명령어를 입력하거나, 응용 프로그램의 아이콘을 더블-클릭하여 프로그램을 실행시키면, 운영체제는 새로운 프로세스를 생성한다.
  • 제거(Destroy) : 프로세스 생성 인터페이스를 제공하는 것처럼 운영체제는 프로세스 를 박제로 제거할 수 있는 인터페이스를 제공해야 한다. 물론, 많은 프로세스는 실행되고 할 일을 다하면 스스로 종료한다. 그러나 프로세스가 스스로 종료하지 않으면 사용자는 그 프로세스를 제거하길 원할 것이고, 필요ᨧ는 프로세스를 중단시키는 API는 매우 유용하다.
  • 대기(Wait) : 때론 어떤 프로세스의 실행 중지를 기다릴 필요가 있기 때문에 여러 종류의 대기 인터페이스가 제공된다.
  • 각종 제어(Miscellaneous Control) : 프로세스의 제거, 대기 이외에, 여러 가지 제어 기능들이 제공된다. 예를 들어, 대부분의 운영체제는 프로세스를 일시정지하거나 재발 (일시정지되ᨩ던 프로세스의 실행을 다시 시작)하는 기능을 제공한다.
  • 상태(Status) : 프로세스 상태 정보를 얻어내는
  • 인터페이스도 제공된다. 상태 정보에는 얼마 동안 실행되ᨩ는지 또는 프로세스가 어떤 상태에 있는지 등이 포함된다.

프로세스 생성 : 좀 더 자세하게

1. Load a program code into memory, into the address space of the process. ( 메모리에 코드 적재 )

  • 프로그램은 디스크 또는 SSD에 실행 파일 형식으로 저장되어 있다. 코드와 정적 데이터를 메모리에 탑재하기 위해서 운영체제는 디스크의 해당 바이트를 읽어서 메모리에 저장한다. 

2. The program's run-time stack is allocated.

  • 일정량의 메모리를 run-time stack 용도로 할당시킨다.
  • main() 함수의 인자인 argc와 argv 벡터를 사용하여 스택을 초기화한다.

3. The program;s heap is created.

  • free(), malloc()

4. The OS do some other initialization tasks.

  • 입출력과 관계된 초기화 작업 수행 (ex. 표준 입력 STDIN, 표준 출력 STDOUT, 표준 에러 STDERR 장치에 해당하는 세 개의 파일 디스크립터)

5. Start the program running at the entry point, namely main().

 

 

프로세스 상태

  • 실행 (Running): 실행 상태에서 프로세스는 프로세서에서 실행 중이다. 즉, 프로세 스는 명령어를 실행하고 있다.
  • 준비 (Ready): 준비 상태에서 프로세스는 실행할 준비가 되어 있지만 운영체제가 다른 프로세스를 실행하고 있는 등의 이유로 대기 중이다.
  • 대기 (Blocked): 프로세스가 다른 사건을 기다리는 동안 프로세스의 수행을 중단시 키는 연산이다. 흔한 예 : 프로세스가 디스크에 대한 입출력 요청을 하였을 때 프로세스는 입출력이 완료될 때까지 대기 상태가 되고, 다른 프로세스가 실행 상태로 될 수 있다.
  • + 최종(final)/좀비(zombie) : 프로세스는 종료되었지만 메모리에 남아있다.

 

 

자료 구조

운영체제도 일종의 프로그램이므로 다양한 정보를 유지하기 위한 자료 구조를 가지고 있다.

 

  • PCB (Process Control Block) : 각 프로세스의 정보를 담고 있는 자료구조

 

 

 


광운대학교 김태석 교수님 운영체제 수업과

[운영체제 : 아주 쉬운 세 가지 이야기] 책 참고

 

'21-2학기 > 운영체제' 카테고리의 다른 글

[Virtualizaton] 4. Limited Direct execution  (0) 2022.01.04
[Virtualizaton] 3. Process API  (0) 2022.01.04

Makefile
0.00MB

 

목표

목표.

이번 작품의 목표는 다량의 데이터가 들어왔을 때 두 개의 서버에서 나누어서 처리하는 분산 처리 서버 구현이었다.

원래 계획했던 작품은 웹페이지로 클라이언트에게 이미지 파일이 압축된 zip 파일을 받고, 메인 서버에서 zip 파일을 압축 해제하며 파일을 byte로 서브 서버에게 전송한다. 그러면 서브 서버가 ocr을 진행한 후 DB에 저장하는 작품이었다.

시스템 아키텍쳐
BARAM_21년도_후반기_제안서_28기_19김다현.hwp
1.36MB

 

문제점

문제점 1.

web으로 클라이언트의 요청을 받으려했는데 그러면 MAIN server를 spring을 이용해 web server로 구현해야 했었다. spring을 사용하기 때문에 java를 사용했다. 근데 sub server는 C로 구현해서 통신이.... 너무 어려웠다.

이미지 하나의 전송까지는 성공했지만 2개부터 잘 되지 않았다..ㅠㅠ

문제점 2.

sub server는 AWS에서 무료로 제공하는 서비스를 이용했다. 근데 AWS에서 무료로 제공하는 서버의 성능이 너무 좋지 않았다. 어느 정도였냐면 tesseract를 사용하기 위해서는 opencv를 설치해야했는데 opencv의 컴파일이 되지 않았다. tesseract 진행 후 DB 구현하는 걸 구현은 해두었는데 서버에 올릴 수 없었다.

 

결과

결과.

그래서 결과적으로는 3개의 서버를 모두 C 서버로 구현해서 소켓통신을 했다.

결과물로는 클라이언트와 로드밸런싱과 DB 저장 정도? 계획했던 작품에 비해서는 결과가 제대로 나오지는 않았지만 load balancing과 socket 통신을 구현해볼 수 있는 기회였다.

설명.

AWS에서 2개의 서버를 대여한 후 아래의 "server.c" 코드(데이터 수신 및 DB 저장)를 각각 서버에 넣어주고 실행파일을 만든 후 서버를 실행시켜준다.

main server의 9999 port를 이용해서 로드밸런서를 구현했으므로 client는 main server의 9999 포트에 접속해서 이미지를 전송한다. 이때 파일 전송은 스레드로 구현해서 속도를 향상시켰다.

클라이언트는 같은 주소로 파일을 전송하지만 서버 두 개가 데이터를 번갈아서 받는 모습을 볼 수 있다. round robbin으로 로드밸런싱을 구현했기 때문에 순차적으로 데이터를 전송받는 것이다.

전송이 끝나면 이미지들이 DB에 저장된다.

 

코드

최종 코드.

https://github.com/ekgus2222/multiserver

 

GitHub - ekgus2222/multiserver: testset

testset. Contribute to ekgus2222/multiserver development by creating an account on GitHub.

github.com

결과 코드는 여기서!

 

 

[HAProxy] TCP 로드밸런싱
https://hyunisland.tistory.com/71

 

[HAProxy] TCP 로드밸런싱

/* * ubuntu 18.04 - 서버 3개 & 클라이언트 * HA-Proxy version : 1.8.40 */ 총 서버는 3개를 준비했다. 하나의 클라이언트에서 HAProxy 서버에 접속하면 HAProxy 서버가 연결된 2개의 서버에 로드밸런싱을 해준..

hyunisland.tistory.com

TCP 로드밸런싱은 여기서!

 

 

 

추가 코드.

[socket 통신] java client & c server 간 이미지 전송
https://hyunisland.tistory.com/68

 

[Tesseract + DB]

OCR + Tesseract
DB 결과

#include<string>
#include<tesseract/baseapi.h>
#include<leptonica/allheaders.h>
#include<opencv4/opencv2/opencv.hpp>

#include "/usr/include/mysql/mysql.h"
#include <string.h>
#include <stdio.h>


void main(int argc, char *argv[])
{
    char* impath = argv[1]; // path 설정
    string outText, imPath = impath;
    Mat im = cv::imread(imPath, IMREAD_COLOR);
    tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();

    api->Init(NULL, "eng", tesseract::OEM_LSTM_ONLY);
    api->SetPageSegMode(tesseract::PSM_AUTO);
    api->SetImage(im.data, im.cols, im.rows, 3, im.step);
    outText = string(api->GetUTF8Text());
    cout<<outText;
    api->End();

    MYSQL       *connection=NULL, conn;
    MYSQL_RES   *sql_result;
    MYSQL_ROW   sql_row;
    int       query_stat; 

    char text[20];
    strcpy(text, outText.c_str());
    char time[80] = "230";
    char query[255];
    
    mysql_init(&conn);

    connection = mysql_real_connect(&conn, DB_HOST,
                                    DB_USER, DB_PASS,
                                    DB_NAME, 3306,
                                    (char *)NULL, 0);

    if (connection == NULL)
    {
        fprintf(stderr, "Mysql connection error : %s", mysql_error(&conn));
        return;
    }

    // query_stat = mysql_query(connection, "select * from text");
    // if (query_stat != 0)
    // {
    //     fprintf(stderr, "Mysql query error : %s", mysql_error(&conn));
    //     return 1;
    // }
    
    // sql_result = mysql_store_result(connection);
    
    // printf("%-11s %-11s %-11s\n", "id", "텍스트", "시간");
    // while ( (sql_row = mysql_fetch_row(sql_result)) != NULL )
    // {
    //     printf("%-11s %-11s %-11s\n", sql_row[0], sql_row[1], sql_row[2]);
    // }

    mysql_free_result(sql_result);

    printf("input text : %s\n", text);
    //fgets(text, 12, stdin);
    CHOP(text);

    printf("input time : %s\n", time);
    //fgets(time, 80, stdin);
    CHOP(time);

    printf("\n");

    sprintf(query, "insert into text(text,time) values ('%s', '%s')",
                   text, time);

    query_stat = mysql_query(connection, query);
    if (query_stat != 0)
    {
        fprintf(stderr, "Mysql query error : %s", mysql_error(&conn));
        return;
    }
    else {
	printf("insert ok\n");
    }

    mysql_close(connection);
}

+ Recent posts