안드로이드 앱이  PHP 프로그램을 매개로 하여 MySQL 데이터베이스 서버에 데이터를 저장하는 간단한 예제입니다.



1. Apache2, MySQL, PHP7 설치

2. 데이터베이스 및 테이블 생성

3. 웹브라우저로 PHP 동작  테스트

4. Android 앱에서 테스트

5. 코드 설명

6. 관련 포스팅

7. 참고



마지막 업데이트 2018. 12. 6




안드로이드 앱에서 바로 MySQL에 접속한다면 구현이 간단할 수 있습니다.

하지만 리버스 엔지니어링을 통해 안드로이드 앱에서 소스코드를 추출하게 되면 서버 아이피와 MySQL 서버 접속용 아이디와 패스워드가 유출될 수 있습니다.


그래서 웹서버에서 실행되는 PHP를 이용하여 진행하게 됩니다.  안드로이드 앱의 코드를 추출한다 해도 서버 IP와 실행되는 PHP 파일 이름만 알 수 있습니다.

하지만 해당 IP와 PHP 파일에 대한 정보를 통해 악용할 수도 있기 때문에 추가로 필요한 작업이 있을 수도 있을 듯하지만 제가 아는 범위에서 벗어나서 논외로 합니다.



1. Apache2, MySQL, PHP7 설치

서버로 사용하려는 운영체제에 따라 1-1 또는 1-2를 진행하세요.

1-1. WIndows

다음 포스팅을 참고하여 윈도우에 WAMP( Apache2, MySQL , PHP7)를 설치합니다.



윈도우 기반 웹 개발 환경 만들기 ( Apache2, PHP, MySQL, PhpMyAdmin )

http://webnautes.tistory.com/1206




오른쪽 아래 시계 옆에 있는 WampServer 트레이 아이콘을 마우스 왼쪽 버튼으로 클릭한 후, 메뉴에서 PHP > Version을 선택합니다.


사용가능한 PHP 버전이 보이는 데 최신 버전인 7.2.4를 선택합니다. 글 작성시점과 버전이 다를 수 있습니다.





1-2. Ubuntu

다음 포스팅을 참고하여 Ubuntu에  LAMP( Apache2, MySQL , PHP7)를 설치합니다.



Ubuntu 18.04에 LAMP ( Apache2, MySQL , PHP7) 설치하는 방법

http://webnautes.tistory.com/1185    





2. 데이터베이스 및 테이블 생성


2-1. MySQL에서 데이터베이스를 새로 생성하고  해당 데이베이스를 접근할 수 있는 사용자를 추가하는 방법을 설명합니다.


서버 컴퓨터의 운영체제가 Windows라면 2-2, Ubuntu라면 2-3을 진행하세요.




2-2. 오른쪽 아래 시계 옆에 있는 WampServer 트레이 아이콘을 마우스 왼쪽 버튼으로 클릭한 후, 메뉴에서 MySQL > MySQL console을 선택합니다.


로그인 사용자로 root가 지정되어 있습니다. OK 버튼을 클릭합니다.




Enter password: 라는 메시지가 보입니다.  설치시 설정해주었던 root 암호를 입력해주면 로그인이 완료됩니다.


root 암호를 설정한 적이 없다면 엔터를 입력하여 진행할 수도 있지만 포스팅의 1-1을 다시 진행하여 root 암호를 부여해주세요..



이제 2-4를 진행하세요.




2-3. Ubuntu 18.04에서 설치한 MySQL에서는 디폴트로 auth_socket 플러그인을 사용하기 때문에 기존에 사용하던 방법(root 계정의 암호입력)으로 로그인이 되지 않습니다.


확인을 못해봤는데 Ubuntu 16.04에서 최신 버전 MySQL을 사용한다면 같은 상황이 있을 수 있습니다.


webnautes@webnautes-pc:~$ mysql -u root -p
Enter password:
ERROR 1698 (28000): Access denied for user 'root'@'localhost'



sudo 명령시 입력하는 사용자 암호 입력으로 기존 로그인을 대체합니다.


webnautes@webnautes-pc:~$ sudo mysql
[sudo] webnautes의 암호:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.7.22-0ubuntu18.04.1 (Ubuntu)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql>




2-4. 윈도우와 우분투에서 동일하게 진행하는 부분입니다.


데이터베이스를 생성합니다.


mysql> create database 데이터베이스이름 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;


mysql> create database testdb default character set utf8;

Query OK, 1 row affected (0.00 sec)



새로 생성한 데이터베이스를 사용할 사용자를 생성합니다.


mysql> create user 사용자이름 identified by '패스워드';


mysql> create user webnautes identified by 'apple9!';

Query OK, 0 rows affected (0.01 sec)



앞에서 생성했던 데이터베이스를 새로 생성한 사용자가 사용하도록 권한을 부여합니다.  


mysql> GRANT ALL PRIVILEGES ON 데이터베이스이름.* TO '사용자이름'@'localhost' identified by '패스워드';


mysql> grant all privileges on testdb.* to 'webnautes'@'localhost' identified by 'apple9!';

Query OK, 0 rows affected, 1 warning (0.00 sec)




2-5.  MySQL 콘솔에 새로 생성한 사용자로 접속합니다.


우분투에서는 다음처럼 MySQL 로그인을 합니다. 사용자 이름은 새로 생성한 데이터베이스 접근권한을 가진 사용자 입니다.

Enter password: 에 사용자의 암호를 입력해줍니다.


$ mysql -u 사용자이름 -p

Enter password:



윈도우에서는 오른쪽 아래 시계 옆에 있는 WampServer 트레이 아이콘을 마우스 왼쪽 버튼으로 클릭한 후, 메뉴에서 MySQL > MySQL console을 선택합니다.


새로 생성한 데이터베이스 접근권한을 가진 사용자 이름을 적고 OK 버튼을 클릭합니다.




Enter password: 메시지가 보이면 사용자의 암호를 입력해줍니다.


Enter password:




2-6. 데이터베이스 testdb에 필요한 테이블 person을 생성하고  MySQL이 잘 동작하는지 여부를 다음처럼 확인합니다.


앞에서 생성해두었던 데이터베이스 testdb가 보입니다.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| testdb             
+--------------------+
2 rows in set (0.00 sec)


데이터베이스 testdb를 사용하도록 하고

mysql> use testdb;
Database changed



다음 명령을 복사 후 붙여넣기 해서 person 테이블을 생성합니다.

create table person(
     id bigint(20) unsigned not null auto_increment,
     name varchar(255) not null,
     country varchar(255) not null,
     primary key (id)
)  DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;


mysql> create table person(
   ->    id bigint(20) unsigned not null auto_increment,
   ->    name varchar(255) not null,
   ->    country varchar(255) not null,
   ->    primary key (id)
   -> )  DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
Query OK, 0 rows affected (0.03 sec)


person 테이블이 생성되었습니다.


mysql> show tables;
+--------------+
| Tables_in_db |
+--------------+
| person       |
+--------------+
1 row in set (0.00 sec)


데이터 하나를 테이블에 입력 해봅니다.


mysql> insert into person(name, country) values('test', 'test');
Query OK, 1 row affected (0.00 sec)


쿼리를 해서 데이터를 다시 가져와 봅니다.


mysql> select * from person;
+----+------+---------+
| id | name | country |
+----+------+---------+
|  1 | test | test    |
+----+------+---------+
1 row in set (0.00 sec)


person 테이블의 데이터를 초기화합니다.


mysql> truncate person;
Query OK, 0 rows affected (0.01 sec)


테이블이 초기화 되었습니다.


mysql> select * from person;

Empty set (0.00 sec)


MySQL 콘솔을 종료합니다.


mysql> exit
Bye




3. 웹브라우저로 PHP 동작  테스트

Android 앱으로 테스트를  진행하기 전에 다음 PHP 코드를  웹 브라우저로 간단한 테스트를 해보겠습니다.


다음 두 개의 파일이 필요합니다.

dbcon.php

MySQL 서버 접속을 위해 사용되는 코드입니다.


insert.php

지정해 높은 데이터베이스의 테이블에 데이터를 저장하기 위해 사용됩니다.



dbcon.php


<?php

   $host = 'localhost';
   $username = 'webnautes'; # MySQL 계정 아이디
   $password = 'apple9!'; # MySQL 계정 패스워드
   $dbname = 'testdb';  # DATABASE 이름


   $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
   
   try {

       $con = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8",$username, $password);
   } catch(PDOException $e) {

       die("Failed to connect to the database: " . $e->getMessage());
   }


   $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $con->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

   if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
       function undo_magic_quotes_gpc(&$array) {
           foreach($array as &$value) {
               if(is_array($value)) {
                   undo_magic_quotes_gpc($value);
               }
               else {
                   $value = stripslashes($value);
               }
           }
       }

       undo_magic_quotes_gpc($_POST);
       undo_magic_quotes_gpc($_GET);
       undo_magic_quotes_gpc($_COOKIE);
   }

   header('Content-Type: text/html; charset=utf-8');
   #session_start();
?>




insert.php


<?php

   error_reporting(E_ALL);
   ini_set('display_errors',1);

   include('dbcon.php');


   if( ($_SERVER['REQUEST_METHOD'] == 'POST') && isset($_POST['submit']))
   {

       $name=$_POST['name'];
       $country=$_POST['country'];

       if(empty($name)){
           $errMSG = "이름을 입력하세요.";
       }
       else if(empty($country)){
           $errMSG = "나라를 입력하세요.";
       }

       if(!isset($errMSG))
       {
           try{
               $stmt = $con->prepare('INSERT INTO person(name, country) VALUES(:name, :country)');
               $stmt->bindParam(':name', $name);
               $stmt->bindParam(':country', $country);

               if($stmt->execute())
               {
                   $successMSG = "새로운 사용자를 추가했습니다.";
               }
               else
               {
                   $errMSG = "사용자 추가 에러";
               }

           } catch(PDOException $e) {
               die("Database error: " . $e->getMessage());
           }
       }

   }
?>

<html>
  <body>
       <?php
       if (isset($errMSG)) echo $errMSG;
       if (isset($successMSG)) echo $successMSG;
       ?>
       
       <form action="<?php $_PHP_SELF ?>" method="POST">
           Name: <input type = "text" name = "name" />
           Country: <input type = "text" name = "country" />
           <input type = "submit" name = "submit" />
       </form>
  
  </body>
</html>




3-1. 윈도우라면 C:\wamp64\www\ 경로에 파일을 생성합니다.



3-2. 우분투라면 /var/www/html/ 경로에 파일을 생성합니다.



3-3. 웹브라우저에서  localhost/insert.php 주소로 접속하면 아래와 같은 화면이 보이게 됩니다.




정상적으로 테이블에 데이터가 입력되면 출력되는 메시지입니다.




이름이나 나라를 입력하지 않으면 에러 메시지를 출력하도록 되어 있습니다.






3-4. 안드로이드 폰의 웹브라우저에서도 테스트해 봅니다.




접속에 문제가 있다면 우선 현재 네트워크를 윈도우에서 공용 네트워크로 인식하고 있는지 확인해봐야 합니다.

파일 탐색기의 왼쪽에 보이는 네트워크 항목에서 마우스 우클릭하여 보이는 메뉴에서 속성을 선택합니다.





다음처럼 공용 네트워크로 되어 있다면 두가지 방법으로 해결할 수 있습니다.




현재 사용중인 네트워크가 신뢰할 수 있는 네트워크(집이나 회사)라면 개인 네트워크로 변경하여 해결할 수 있습니다.

외부 카페 같은 곳이라면 방어벽의 설정에서 공용 네트워크에서도 아파치 웹서버에 접속가능하도록 해주면 됩니다.



자세한 내용은 다음 포스팅의 17번을 참고하세요.



윈도우 기반 웹 개발 환경 만들기 ( Apache2, PHP, MySQL, PhpMyAdmin )

http://webnautes.tistory.com/1206





3-5. MySQL에서 확인해보면 데이터가 정상적으로 입력된 것을 볼 수 있습니다.


SELECT 문으로 testdb 데이터베이스에 있는 Person 테이블의 내용을 조회합니다.

웹에서 입력한 이름과 주소가 제대로 입력되었는지 확인가능합니다.





..


..


4. Android 앱에서 테스트


웹서버의 PHP 파일을 통해 데이터베이스에 데이터를 저장하는 안드로이드 앱을 작성합니다.



4-1. 다음 코드로 insert.php 파일의 내용을 대체합니다.


insert.php 파일에 다음처럼 노란 줄을 수정합니다.

안드로이드에서 접속한 거라면 웹 유저 인터페이스를 안보이도록 하는 역할을 합니다.



<?php

   error_reporting(E_ALL);
   ini_set('display_errors',1);

   include('dbcon.php');


   $android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");


   if( (($_SERVER['REQUEST_METHOD'] == 'POST') && isset($_POST['submit'])) || $android )
   {

       // 안드로이드 코드의 postParameters 변수에 적어준 이름을 가지고 값을 전달 받습니다.

       $name=$_POST['name'];
       $country=$_POST['country'];

       if(empty($name)){
           $errMSG = "이름을 입력하세요.";
       }
       else if(empty($country)){
           $errMSG = "나라를 입력하세요.";
       }

       if(!isset($errMSG)) // 이름과 나라 모두 입력이 되었다면
       {
           try{
               // SQL문을 실행하여 데이터를 MySQL 서버의 person 테이블에 저장합니다.
               $stmt = $con->prepare('INSERT INTO person(name, country) VALUES(:name, :country)');
               $stmt->bindParam(':name', $name);
               $stmt->bindParam(':country', $country);

               if($stmt->execute())
               {
                   $successMSG = "새로운 사용자를 추가했습니다.";
               }
               else
               {
                   $errMSG = "사용자 추가 에러";
               }

           } catch(PDOException $e) {
               die("Database error: " . $e->getMessage());
           }
       }

   }

?>


<?php
   if (isset($errMSG)) echo $errMSG;
   if (isset($successMSG)) echo $successMSG;

$android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");
  
   if( !$android )
   {
?>
   <html>
      <body>

           <form action="<?php $_PHP_SELF ?>" method="POST">
               Name: <input type = "text" name = "name" />
               Country: <input type = "text" name = "country" />
               <input type = "submit" name = "submit" />
           </form>
      
      </body>
   </html>

<?php
   }
?>




4-2. AndroidManifest.xml 매니페스트 파일의  manifest 태그 하위 항목으로 인터넷 접근 허용 퍼미션을 추가합니다.




<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.tistory.webnautes.phptest">

   <uses-permission android:name="android.permission.INTERNET" />

   <application
       android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"



4-3. activity_main.xml 레이아웃 파일을 아래 내용으로 바꿉니다.



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   tools:context=".MainActivity">

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Name"
       android:id="@+id/textView_main_name" />

   <EditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/editText_main_name" />

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Country"
       android:id="@+id/textView_main_country" />

   <EditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/editText_main_country" />

   <Button
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="Insert"
       android:id="@+id/button_main_insert" />

   <TextView
       android:layout_width="match_parent"
       android:layout_height="250dp"
       android:id="@+id/textView_main_result" />

</LinearLayout>




4-4. MainActivity.java 자바 파일을 아래 내용으로 바꿉니다.



다음 줄에 있는 IP 주소를 아파치 웹서버가 설치된  컴퓨터의 IP로 수정하세요.

private static String IP_ADDRESS = "IP주소";


안드로이드 에뮬레이터와 서버가 같은 컴퓨터에 동작하는 경우에는 다음 아이피를 입력합니다.

Android Studio의 에뮬레이터  - 10.0.2.2

GenyMotion - 192.168.56.1  


package com.tistory.webnautes.phptest;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.BufferedReader;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import java.net.HttpURLConnection;
import java.net.URL;


public class MainActivity extends AppCompatActivity {

   private static String IP_ADDRESS = "IP주소";
   private static String TAG = "phptest";

   private EditText mEditTextName;
   private EditText mEditTextCountry;
   private TextView mTextViewResult;


   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       mEditTextName = (EditText)findViewById(R.id.editText_main_name);
       mEditTextCountry = (EditText)findViewById(R.id.editText_main_country);
       mTextViewResult = (TextView)findViewById(R.id.textView_main_result);

       mTextViewResult.setMovementMethod(new ScrollingMovementMethod());


       Button buttonInsert = (Button)findViewById(R.id.button_main_insert);
       buttonInsert.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {

               String name = mEditTextName.getText().toString();
               String country = mEditTextCountry.getText().toString();

               InsertData task = new InsertData();
               task.execute("http://" + IP_ADDRESS + "/insert.php", name,country);


               mEditTextName.setText("");
               mEditTextCountry.setText("");

           }
       });

   }



   class InsertData extends AsyncTask<String, Void, String>{
       ProgressDialog progressDialog;

       @Override
       protected void onPreExecute() {
           super.onPreExecute();

           progressDialog = ProgressDialog.show(MainActivity.this,
                   "Please Wait", null, true, true);
       }


       @Override
       protected void onPostExecute(String result) {
           super.onPostExecute(result);

           progressDialog.dismiss();
           mTextViewResult.setText(result);
           Log.d(TAG, "POST response  - " + result);
       }


       @Override
       protected String doInBackground(String... params) {

           String name = (String)params[1];
           String country = (String)params[2];

           String serverURL = (String)params[0];
           String postParameters = "name=" + name + "&country=" + country;


           try {

               URL url = new URL(serverURL);
               HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();


               httpURLConnection.setReadTimeout(5000);
               httpURLConnection.setConnectTimeout(5000);
               httpURLConnection.setRequestMethod("POST");
               httpURLConnection.connect();


               OutputStream outputStream = httpURLConnection.getOutputStream();
               outputStream.write(postParameters.getBytes("UTF-8"));
               outputStream.flush();
               outputStream.close();


               int responseStatusCode = httpURLConnection.getResponseCode();
               Log.d(TAG, "POST response code - " + responseStatusCode);

               InputStream inputStream;
               if(responseStatusCode == HttpURLConnection.HTTP_OK) {
                   inputStream = httpURLConnection.getInputStream();
               }
               else{
                   inputStream = httpURLConnection.getErrorStream();
               }


               InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
               BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

               StringBuilder sb = new StringBuilder();
               String line = null;

               while((line = bufferedReader.readLine()) != null){
                   sb.append(line);
               }


               bufferedReader.close();


               return sb.toString();


           } catch (Exception e) {

               Log.d(TAG, "InsertData: Error ", e);

               return new String("Error: " + e.getMessage());
           }

       }
   }


}




4-5.  안드로이드 프로젝트를 빌드하여 앱을 테스트할 디바이스 또는 에뮬레이터에 설치합니다.

앱을 실행시키면 다음과 같은 화면이 보입니다.




테스트 문자열을 입력하고  INSERT를 터치합니다.




성공한 경우 SQL문 처리 성공이라는 메시지가 보이게 됩니다.




Error: connect timed out 메시지가 보인다면 본 포스팅의 3-4를 다시 확인해보세요.

방어벽 문제 일 수 있습니다.




4-6. MySQL에서 확인해보면 정상적으로 입력된 것을 볼 수 있습니다.





5. 코드 설명

다음 두 단계를 거쳐서 안드로이드 앱의 데이터가 MySQL 서버에 저장됩니다.


  1. 안드로이드 앱에서 POST 방식으로 PHP 코드에 데이터를 전달합니다.

  2. PHP 코드에서 MySQL 서버에 접속하여 전달받은 데이터를 저장합니다.



우선 안드로이드 앱 코드를 살펴보겠습니다.


@Override
protected String doInBackground(String... params) {

String name = (String)params[1];
String country = (String)params[2];


     // 1. PHP 파일을 실행시킬 수 있는 주소와 전송할 데이터를 준비합니다.

     // POST 방식으로 데이터 전달시에는 데이터가 주소에 직접 입력되지 않습니다.
String serverURL = (String)params[0];



     // HTTP 메시지 본문에 포함되어 전송되기 때문에 따로 데이터를 준비해야 합니다.

     // 전송할 데이터는 “이름=값” 형식이며 여러 개를 보내야 할 경우에는 항목 사이에 &를 추가합니다.     

     // 여기에 적어준 이름을 나중에 PHP에서 사용하여 값을 얻게 됩니다.

     String postParameters = "name=" + name + "&country=" + country;


try {
           // 2. HttpURLConnection 클래스를 사용하여 POST 방식으로 데이터를 전송합니다.
URL url = new URL(serverURL); // 주소가 저장된 변수를 이곳에 입력합니다.


           HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

httpURLConnection.setReadTimeout(5000); //5초안에 응답이 오지 않으면 예외가 발생합니다.

httpURLConnection.setConnectTimeout(5000); //5초안에 연결이 안되면 예외가 발생합니다.

httpURLConnection.setRequestMethod("POST"); //요청 방식을 POST로 합니다.
httpURLConnection.connect();


OutputStream outputStream = httpURLConnection.getOutputStream();
outputStream.write(postParameters.getBytes("UTF-8")); //전송할 데이터가 저장된 변수를 이곳에 입력합니다. 인코딩을 고려해줘야 합니다.

outputStream.flush();
outputStream.close();


           // 3. 응답을 읽습니다.   

int responseStatusCode = httpURLConnection.getResponseCode();
Log.d(TAG, "POST response code - " + responseStatusCode);

InputStream inputStream;
if(responseStatusCode == HttpURLConnection.HTTP_OK) {

                 // 정상적인 응답 데이터
inputStream = httpURLConnection.getInputStream();
}
else{

                 // 에러 발생

inputStream = httpURLConnection.getErrorStream();
}


           // 4. StringBuilder를 사용하여 수신되는 데이터를 저장합니다.
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

StringBuilder sb = new StringBuilder();
String line = null;

while((line = bufferedReader.readLine()) != null){
sb.append(line);
}


bufferedReader.close();

           

           // 5. 저장된 데이터를 스트링으로 변환하여 리턴합니다.
return sb.toString();


} catch (Exception e) {

Log.d(TAG, "InsertData: Error ", e);

return new String("Error: " + e.getMessage());
}

}




PHP 코드를 보겠습니다.

       // 1. 안드로이드 코드의 postParameters 변수에 적어준 이름을 가지고 값을 전달 받습니다.
       $name=$_POST['name'];
       $country=$_POST['country'];


   
       // 2. 입력안된 항목이 있을 경우 에러 메시지를 생성합니다.
       if(empty($name)){
           $errMSG = "이름을 입력하세요.";
       }
       else if(empty($country)){
           $errMSG = "나라를 입력하세요.";
       }

       // 3. 에러 메시지가 정의안되어 있다면 이름과 나라 모두 입력된 경우입니다.

       if(!isset($errMSG))
       {
           try{
               // 4. SQL문을 실행하여 데이터를 MySQL 서버의 person 테이블에 저장합니다.
               $stmt = $con->prepare('INSERT INTO person(name, country) VALUES(:name, :country)');
               $stmt->bindParam(':name', $name);
               $stmt->bindParam(':country', $country);

               // 5. SQL 실행 결과를 위한 메시지를 생성합니다.
               if($stmt->execute())
               {
                   $successMSG = "새로운 사용자를 추가했습니다.";
               }
               else
               {
                   $errMSG = "사용자 추가 에러";
               }



6. 관련 포스팅



Android PHP MySQL 예제 - 데이터베이스에서 데이터를 JSON 형식으로 가져오기

http://webnautes.tistory.com/829


Android PHP MySQL 예제 - 데이터베이스 질의(query) 결과 출력하기

https://webnautes.tistory.com/1159


Android PHP MySQL 예제  - 데이터베이스에 데이터 저장 및 JSON 형식으로 가져오는 예제 프로젝트

http://webnautes.tistory.com/1189  





7. 참고


[1]  http://www.simplifiedcoding.net/php-android-tutorial-part-1/


[2]  http://www.simplifiedcoding.net/android-login-and-registration-with-php-mysql/


[3]  http://www.tutorialspoint.com/android/android_php_mysql.htm



포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.


여러분의 응원으로 좋은 컨텐츠가 만들어집니다. 지금 본 내용이 도움이 되었다면 후원을 부탁드립니다. 감사합니다 : )
후 원 하 기


페이스북 페이지 : www.facebook.com/webnautes/

유튜브 채널 : youtube.com/user/webnautes


감사합니다 : )



  1. 이전 댓글 더보기
  2. 2018.11.16 15:34

    비밀댓글입니다

  3. 용전동사람 2018.11.29 17:05

    웹이나 폰에서는 DB입력이 정상적으로되는대 안드로이드 어플에서는 추가시킬려고하니 result 메시지에 php에 있는 html 코드들이 나오는대 어떤 문제인가요???

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2018.11.29 17:25 신고

      4-1에 있는 코드로 바꿔야 합니다

    • 용전동사람 2018.11.29 17:29

      헐,.. 바꾸니 정상작동되네요;; 혹시 어떤 부분이 변경된건지 간략하게라도 알수있을가요??

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2018.11.29 17:34 신고

      안드로이드에서는 웹 UI를 출력못하게 막아놓았슺니다.

    • 용전동사람 2018.11.29 17:37

      아 정말감사합니다 댓글보니 위애분도 저랑 같은 상황이였네요 ㅎㅎ 많은걸 배우고갑니다 ㅎㅎ

  4. 2018.12.06 22:24

    비밀댓글입니다

  5. 우성이 2018.12.10 00:35

    오류는 안뜨는데 데이터베이스에 추가가안됩니다 ㅠㅠ 웹에서 실행하면 잘되는데 왜 안되는지 모르겠네요..
    로그는
    2018-12-10 00:33:01.567 7191-7212/com.example.lee.myapplication D/phptest: POST response code - 200
    2018-12-10 00:33:01.709 7191-7191/com.example.lee.myapplication D/phptest: POST response - 
    이렇게 뜨고

    처음에는 위에 댓글과 같이 html코드 나오길래 4.1코드 번경하니 $android가 정의가 안되있다고오류 뜨더군요..
    그래서

    <?php

    error_reporting(E_ALL);
    ini_set('display_errors',1);

    include('dbcon.php');


    if( ($_SERVER['REQUEST_METHOD'] == 'POST') && isset($_POST['submit']))
    {

    $name=$_POST['name'];
    $country=$_POST['country'];

    if(empty($name)){
    $errMSG = "이름을 입력하세요.";
    }
    else if(empty($country)){
    $errMSG = "나라를 입력하세요.";
    }

    if(!isset($errMSG))
    {
    try{
    $stmt = $con->prepare('INSERT INTO person(name, country) VALUES(:name, :country)');
    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':country', $country);

    if($stmt->execute())
    {
    $successMSG = "새로운 사용자를 추가했습니다.";
    }
    else
    {
    $errMSG = "사용자 추가 에러";
    }

    } catch(PDOException $e) {
    die("Database error: " . $e->getMessage());
    }
    }

    }
    ?>
    <?php
    if (isset($errMSG)) echo $errMSG;
    if (isset($successMSG)) echo $successMSG;

    $Android = stripos($_SERVER['HTTP_USER_AGENT'], "Android");
    if (!$Android)
    {
    ?>
    <html>
    <body>

    <form action="<?php $_PHP_SELF ?>" method="POST">
    Name: <input type = "text" name = "name" />
    Country: <input type = "text" name = "country" />
    <input type = "submit" name = "submit" />
    </form>

    </body>
    </html>

    <?php
    }
    ?>

    이렇게 변경해 줬더니 실행은 잘되는거같은데 여전히 데이터베이스는 추가가안됩니다..
    왜이럴까요 ㅠㅠ

    • 지나가던사람 2018.12.10 03:28

      && isset($_POST['submit']) 지워보세여

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2018.12.10 08:51 신고

      업데이트하면서 실수했네요. 지금 다시 수정해놓은 코드를 사용하세요

  6. 흑흑 2019.02.12 11:45

    root에서 만든 데이터 베이스가 새로 생성한 사용자로 접속하면 뜨지 않습니다ㅠㅠ 왜그런 걸까요ㅠㅠ 제가 wampp 깔기전에 깔아둔 mysql이 있어서 그런 걸까요??ㅜㅜ 항상 잘보고 있습니다 감사합니다!

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.02.12 11:47 신고

      새로 생성한 사용자에게 해당 데이터베이스 테이블 사용권한이 부여되지 않은듯 합니다. 다시 해보세요

  7. hello 2019.03.27 17:33

    안녕하세요.
    글 중간 4-1 에 노란 줄을 따라 수정하라고 하셨는데, 4-1 에선 노란줄이 안보이는 것 같아서 알려드립니다.
    강의 항상감사드립니다!

  8. KK 2019.03.31 02:15

    좋은 정보에요ㅠ
    근데 저는 보면서 따라하는데
    핸드폰 웹 브라우저로 가면 응답하는 시간이 너무 오래 걸린다고
    나오는데 어떻해야 하나요ㅠ
    노트북에서는 잘 됩니다.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.03.31 08:08 신고

      Mysql설치한 컴퓨터와 스마트폰이 같은 공유기를 쓰나요?

    • KK 2019.03.31 14:29

      네ㅠㅠ
      지금 노트북이랑 핸드폰이랑 같은 와이파이 사용중인데
      노트북에서는 잘만 나오는데
      핸드폰은 계속 안나와요ㅠㅠㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.03.31 20:10 신고

      포스트에 insert.php 코드가 두군데 있습니다.

      스마트폰의 웹브라우저에서 테스트하려면

      3. 웹브라우저로 PHP 동작 테스트 항목에 있는 코드를 사용해야 합니다.

      현재 코드가 아래처럼 보인다면

      <?php
      if (isset($errMSG)) echo $errMSG;
      if (isset($successMSG)) echo $successMSG;

      $android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");

      if( !$android )
      {
      ?>
      <html>
      <body>

      <form action="<?php $_PHP_SELF ?>" method="POST">
      Name: <input type = "text" name = "name" />
      Country: <input type = "text" name = "country" />
      <input type = "submit" name = "submit" />
      </form>

      </body>
      </html>

      <?php
      }
      ?>


      다음처럼 수정하세요..

      <html>
      <body>
      <?php
      if (isset($errMSG)) echo $errMSG;
      if (isset($successMSG)) echo $successMSG;
      ?>

      <form action="<?php $_PHP_SELF ?>" method="POST">
      Name: <input type = "text" name = "name" />
      Country: <input type = "text" name = "country" />
      <input type = "submit" name = "submit" />
      </form>

      </body>
      </html>

  9. 1 2019.04.10 10:46

    웹에서는 디비에 저장이되는데 어플에서는 안되네요 왜그럴까요?

  10. 히히 2019.05.13 12:47

    회원가입 화면 만들고 있어서 테이블 속성이 다섯개인데 이렇게 코드가 되는것 맞나요?ㅠ 실행도 되고 에러도 안나는데 안드로이드스튜디오 가상머신에서 값을 입력하면 테이블에 안들어가요ㅠㅠ

    protected String doInBackground(String... params) {

    String name = (String)params[1];
    String id = (String)params[2];
    String password = (String)params[3];
    String department = (String)params[4];
    String phonenum = (String)params[5];

    String serverURL = (String)params[0];
    String postParameters = "&name=" + name + "&id=" + id+ "&password=" + password
    + "&department=" + department+ "&phonenum=" + phonenum;

    여기는 insert.php에요ㅠ
    <?php

    error_reporting(E_ALL);
    ini_set('display_errors',1);

    include('dbcon.php');


    if( ($_SERVER['REQUEST_METHOD'] == 'POST') && isset($_POST['submit']))
    {

    $name=$_POST['name'];
    $id=$_POST['id'];
    $password=$_POST['password'];
    $department=$_POST['department'];
    $phonenum=$_POST['phonenum'];

    if(empty($name)){
    $errMSG = "insert name.";
    }
    else if(empty($id)){
    $errMSG = "insert id.";
    }
    else if(empty($password)){
    $errMSG = "insert password.";
    }
    else if(empty($department)){
    $errMSG = "insert department.";
    }
    else if(empty($phonenum)){
    $errMSG = "insert phonenumber.";
    }

    if(!isset($errMSG))
    {
    try{
    $stmt = $con->prepare('INSERT INTO login(name, id, password, department, phonenum) VALUES(:name, :id, :password, :department, :phonenum)');
    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':id', $id);
    $stmt->bindParam(':password', $password);
    $stmt->bindParam(':department', $department);
    $stmt->bindParam(':phonenum', $phonenum);


    if($stmt->execute())
    {
    $successMSG = "success";
    }
    else
    {
    $errMSG = "error";
    }

    } catch(PDOException $e) {
    die("Database error: " . $e->getMessage());
    }
    }

    }
    ?>

    <?php
    if (isset($errMSG)) echo $errMSG;
    if (isset($successMSG)) echo $successMSG;

    $android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");

    if( !$android )
    {
    ?>
    <html>
    <body>


    <form action="<?php $_PHP_SELF ?>" method="POST">
    Name: <input type = "text" name = "name" />
    id: <input type = "text" name = "id" />
    password: <input type = "text" name = "password" />
    department: <input type = "text" name = "department" />
    phonenum: <input type = "text" name = "phonenum" />
    <input type = "submit" name = "submit" />
    </form>

    </body>
    </html>

    <?php
    }
    ?>

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.13 14:15 신고

      안드로이드 코드도 수정하셨나요?

      다음 두 부분을 수정해야 합니다.

      1.
      package com.tistory.webnautes.phptest;

      import android.app.ProgressDialog;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.support.v7.app.AppCompatActivity;
      import android.text.method.ScrollingMovementMethod;
      import android.util.Log;
      import android.view.View;
      import android.widget.Button;
      import android.widget.EditText;
      import android.widget.TextView;

      import java.io.BufferedReader;

      import java.io.InputStream;
      import java.io.InputStreamReader;
      import java.io.OutputStream;

      import java.net.HttpURLConnection;
      import java.net.URL;


      public class MainActivity extends AppCompatActivity {

      private static String IP_ADDRESS = "IP주소";
      private static String TAG = "phptest";

      private EditText mEditTextName;
      private EditText mEditTextCountry;
      private TextView mTextViewResult;


      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      mEditTextName = (EditText)findViewById(R.id.editText_main_name);
      mEditTextCountry = (EditText)findViewById(R.id.editText_main_country);
      mTextViewResult = (TextView)findViewById(R.id.textView_main_result);

      mTextViewResult.setMovementMethod(new ScrollingMovementMethod());


      Button buttonInsert = (Button)findViewById(R.id.button_main_insert);
      buttonInsert.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {

      String name = mEditTextName.getText().toString();
      String country = mEditTextCountry.getText().toString();

      InsertData task = new InsertData();
      task.execute("http://" + IP_ADDRESS + "/insert.php", name,country);



      2.
      String name = (String)params[1];
      String country = (String)params[2];

      String serverURL = (String)params[0];
      String postParameters = "name=" + name + "&country=" + country;


  11. ㅎㅎ 2019.05.14 21:57

    안녕하세요 웹서버로 php 테스트를 해봤는데 웹 서버에서는 잘 되는데요 mysql console창에서 확인을 해보려고 했는데 비밀번호를 맞게 쳐도 error가 뜨면서 콘솔창이 그냥 꺼지네요ㅜㅜ 왜이런지 알수 있을까요

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.14 22:06 신고

      mysql이 설치된 환경에 따라 달라서 확답하기가 어렵네요.

      어떤 에러가 보이는지요?

    • ㅎㅎ 2019.05.14 22:25

      uesr 이름때문이었어요ㅜㅜ 감사합니다

  12. hwangbo 2019.05.15 14:29

    안드로이드로 실핼시킬때 값을 입력하고 insert 버튼을 누르면 아무것도 안떠요.. 똑같이 따라했는데 왜그러죠 ㅠㅠ
    에러메세지도 안뜨고 성공했다는 메세지도 안뜹니다.

  13. loating 2019.05.18 15:02

    저도 위의 몇몇분들과 비슷한 현상인데, 웹에서는 잘 되는데 어플로 실행하면 db에 들어가지 않네요..ㅠㅠ 안드로이드 9.0버전이라서 그런건지.. ㅜㅜ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.18 18:07 신고

      외부에서 서버 접속이 가능한지 테스트해보세요

      모바일에서 아파치 웹서버 접속이 가능한지 ...

      모바일 웹브라우저에서 PC 아이피를 입력해서 아파치 웹서버 정보가 보이는지 보세요.

  14. 코린이 2019.05.23 03:40

    php 파일이 브라우저에서도 안열립니다...$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
    이부분이 오류라고하는데 어떤문제일까요....

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.23 08:11 신고

      php7로 바꾸었나요?

    • 코린이 2019.05.25 03:51

      할당받은 php 문제여서 직접 wamp깔고 하고있습니다!! 웹에서는 잘동작하는데 모바일브라우저로는 안되네요...

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.25 08:20 신고

      다음 포스트의 17번대로 포트 80을 열어보세요..

      또한 18번에 소개한대로 개인 네트워크로 변경해야 합니다.

      윈도우 기반 웹 개발 환경 만들기 ( Apache2, PHP, MySQL, PhpMyAdmin )
      https://webnautes.tistory.com/1206

  15. 허접한대학생 2019.05.23 14:43

    안녕하십니까 강의글보고 너무 도움을 많이 받고 있는 대학생입니다. 질문하나가 있어서 여쭤보려 합니다.
    $stmt = $con->prepare('INSERT INTO person(name, country) VALUES(:name, :country)');
    에서 person 이라는 테이블명을 혹시 변수로 대체 가능한지 여쭤보고싶습니다!

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.23 14:45 신고

      values값에서 한것처럼 해보세요..

    • 허접한대학생 2019.05.23 16:13

      Database error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''person'(name, country) VALUES('asd', 'asd')' at line 1


      $table = 'person';
      $stmt = $con->prepare('INSERT INTO :person(name, country) VALUES(:name, :country)');
      $stmt->bindParam(':person', $table);
      이런식으로 해보았는데 위에 에러가 납니다..ㅠㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.23 16:15 신고

      아니면 문자열 조합으로 해야 할듯합니다.

    • 허-대 2019.05.23 16:20

      $stmt = $con->prepare('INSERT INTO' +:person+'(name, country) VALUES(:name, :country)');

      이런식으로 말씀하신건가요.. 뭐 될만한건 다해봤는데 잘 안되네요ㅠㅠ 제가 php언어에 대해 아무것도 몰라서요 ㅠㅠ 혹시 다른방법은 없을까요ㅠㅠㅠ

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.23 17:57 신고

      다음처럼 해보세요.

      $table_name='person';

      $stmt = $con->prepare('INSERT INTO $table_name (name, country) VALUES(:name, :country)');

    • 허접한대학생 2019.05.23 21:54

      Database error: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testdb.$table_name' doesn't exist
      이거는 제가 찾아보고 이미 해봤었는데 이런 에러가 납니당.. 변수로 선언하는것이 아예 불가능한건지..ㅠㅠㅠㅠ 너무 어렵네요

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.24 05:18 신고

      다음처럼 해보세요.
      prepare에 ' 대신에 "를 사용합니다.


      $table='person';
      $stmt = $con->prepare("INSERT INTO $table(name, country) VALUES(:name, :country)");

      $stmt->bindParam(':name', $name);
      $stmt->bindParam(':country', $country);

  16. 코린이 2019.05.25 03:49

    웹브라우저에서 잘동작되는걸 확인하고 모바일 브라우저에서 실행시키는데 접속이 너무오래걸리네요.....
    같은공유기를 사용하고있는데...어떤문제일까요? php는 확실하게 웹용으로 했습니다. 어플용으로 수정안하고요...
    도움을 주시면 감사하겠습니다.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.05.25 08:19 신고

      다음 포스트의 17번대로 포트 80을 열어보세요..

      또한 18번에 소개한대로 개인 네트워크로 변경해야 합니다.

      윈도우 기반 웹 개발 환경 만들기 ( Apache2, PHP, MySQL, PhpMyAdmin )
      https://webnautes.tistory.com/1206

  17. 컴공 2019.05.27 01:47

    안드로이드에서는 POST response code - 200이라고 뜨는데 해당 php 파일을 새로고침하면 no id라고 뜨는데 왜 그런 건가요.?

  18. 따라하는듕 2019.06.01 00:15

    안녕하세요!! 게시글 보고 따라하고 있는데
    이름이랑 나라대신 아이디와 비밀번호로 하고싶어서요
    db에 들어갈 때 암호화가 되지않아서
    mariadb처럼 AES_ENCRYPT('비번','키')) 을
    insert.php에
    $stmt = $con->prepare('INSERT INTO lockuser(uid, upass) VALUES(:uid,HEX(AES_ENCRYPT(:upass,'key')));
    넣었는데 웹페이지가 뜨지 않네요...
    혹시 php 암호화에 대해 아시면 알려주시면 감사하겠습니다.
    게시글잘보고갑니다!

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.06.01 10:03 신고

      아래 포스트를 참고하세요..

      PHP로 간단한 웹사이트 만들기(회원가입, 로그인)
      https://webnautes.tistory.com/1188

    • . 2019.06.02 17:49

      감사합니다

  19. kkdm 2019.06.08 19:26

    안녕하세요 컴퓨터 모바일 웹상에서는 데이터베이스가 잘 작동하는데 어플상에서는 inert 누를 경우 아래 php 글자들 <html> <body> <form action> 이런 문구만 뜨고 데이터베이스에 상빕이 되지 않아서 문의드려요 insert는 아래 있는거 사용했습니다.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.06.08 19:30 신고

      php파일에 다음 부분이 있는 파일인가 보세요.
      html문이 보이지 않게 되어있습니다.


      $android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");
        
         if( !$android )

  20. 나그네 2019.06.26 01:35

    4. Android 앱에서 테스트 라는 항목에소개된 있는 insert.php 파일과 그 전에 첨부된 insert.php 파일의 내용이 조금 차이가있습니다.
    줄번호로는 대략 9번째줄쯤 아래내용이 나중파일에 추가 및 수정되어있구요

    $android = strpos($_SERVER['HTTP_USER_AGENT'], "Android");
    if( (($_SERVER['REQUEST_METHOD'] == 'POST') && isset($_POST['submit'])) || $android )

    나중 파일을 전체 복붙해서 사용하니 제대로 동작이 되는데 노란텍스트만 기존파일에 추가 사용하니 안드로이드에서 db로 데이터가 저장되지 않습니다.
    참조들 하세요

    좋은 자료 감사합니다.~~

  21. 나그네 2019.06.26 16:01

    파이DB에 로컬이 아닌 외부에서 원격으로 php통한 db 데이터저장관련 문의가 있습니다.
    아래와 같은 작업은 진행하였습니다.

    1.파이 설정파일
    sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
    #bind-address = 127.0.0.1 주석처리

    2. 공유기 DDNS 등록 및 포트포워딩 외부 포트 "3306" 내부포트 "22" 설정

    3. 안드로이드 JAVA 파일 IP주소 DDNS 주소 지정
    예) private static String IP_ADDRESS = "goodserver.iptime.org";

    4. mysql root 계정으로 디비에 대한 유저 전체권한설정 예) privileges db파일.* 계정@'%'

    dbcon.php 파일에 $host = 'localhost'; localhost는 지우는게 맞을까요?

    폰에서는 lte로 연결했더니 please wait메세지만 나타나고 있는걸봐서 설정이 틀린것 같긴합니다.
    혹시 놓치고 있는게 있는지 알려주시면 감사하겠습니다.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes webnautes 2019.06.26 16:25 신고

      dbcon.php 파일에서 localhost는 그냥 두는게 맞습니다.

      우선 PC에서 웹브라우저로 아파치웹서버에 있는 웹문서에 접근가능한지 보세요..

      그리고 /var/log/apache2/ 위치에 있는 로그파일을 확인하여 접속 시도가 있었는지 확인 해보는게 좋을듯합니다.

      시도한 흔적이 없다면 설정한 DDNS로 접근이 불가능한 상황같습니다.

+ Recent posts