오라클 클라우드에 서버 인스턴스를 생성하고 FTP로 접속을 하는 방법입니다.

OCI에 서버 인스턴스 생성하기를 보시려면 전에 작성한 글을 참고 하세요.


[OCI] Oracle Cloud 평생 무료 서버 만들기

 

 

FTP로 접속을 위해서는 인스턴스의 Public IP를 확인해야 합니다.

오라클 클라우드에 접속해서 인스턴스 페이지로 이동 합니다.

 

 

좌측 하단 Compartment에서 root를 선택하여 실행중인 인스턴스를 확인 합니다.

root 이외에 다른 이름으로 생성하였다면 접속할 compartment를 선택하면 됩니다.

 

 

저는 아직 하나만 생성해서 리스트에 하나만 나옵니다.

여기서 Public IP가 외부에서 서버로 FTP 접속할때 사용하는 IP 입니다.

IP는 확인 했으니 WindowsFTP Client에서 접속하는 방법을 알아 봅니다.

 

 

1. FileZilla 접속 설정

 

먼저 FileZilla를 이용한 접속 설정 방법입니다.

윈도우에서 FileZilla를 실행합니다.

 

 

메뉴에서 [파일 > 사이트 관리자]를 선택 합니다.

 

 

그리고 사이트 관리자 팝업 창에서 New Site 버튼을 클릭하고 접속 정보를 입력 합니다.

저는 기존에 생성해놓고 사용하지 않는 접속정보가 있어서 새 사이트2를 그냥 이용했습니다.

 

프로토콜 : SFTP 선택

호스트 : OCI에서 확인한 Public IP를 입력해 줍니다.

포트 : 22 (입력 안해도 SFTP 기본으로 접속합니다)

로그온 유형 : 키 파일 선택

사용자 : opc (최초 사용자는 opc 입니다)

키 파일 : 찾아보기 버튼을 클릭해서

 

 

인스턴스를 만들때 저장해 놓은 키 xxx(각자 저장할때 만든 파일명).key를 선택 합니다.

 

 

모든 접속정보를 입력 했으면 [연결] 버튼을 클릭 합니다.

 

 

새로 접속하려는 사이트 연결 정보가 나오면 [확인] 버튼을 클릭 합니다.

 

 

접속이 완료되었습니다.

 

 

2. WinSCP 접속 방법

 

이번에는 WinSCP를 이용하여 Oracle Cloud Server에 접속하는 방법입니다.

FileZilla와 동일하고 키 설정하는 부분만 차이가 있습니다.

WinSCP를 실행 합니다.

 

 

실행하면서 바로 Login 팝업 창이 나타납니다.

Login 팝업 창이 안보이면 New Session 탭을 클릭해 줍니다.

 

 

FileZilla와 동일하게 Public IPopc 등 접속정보를 입력합니다.

 

키를 등록하는데 기존에 저장한 키(확장자 key)를 인식하지 못하여 ppk로 변경하는 작업을 진행하고 키를 등록해야 합니다.  그냥 아래 순서대로 진행하면 됩니다.

 

키를 등록하기 위하여 [Advanced] 버튼을 클릭 하고 Advanced를 선택해 줍니다.

 

 

Advanced Site Settings 팝업 창이 나타납니다.

좌측 메뉴에서 SSH > Authentication을 선택하고

우측에서 Private key file:에서 찾기 버튼(...)을 클릭 합니다.

 

 

WinSCPkey 확장자 파일은 안보이기 때문에 All Files를 선택해야 합니다.

그리고 xxxx.key 파일을 선택해 주는데 WinSCPPuTTY에서 생성하는 키 형태를 지원하므로 변경을 하겠다고 합니다.

 

 

파일을 PuTTY 형태로 변경을 위하여 [OK] 버튼을 클릭 합니다. 

 

 

그럼 변경된 파일을 저장할 위치를 물어보는데 그냥 동일한 위치를 선택하고 [저장] 버튼을 클릭합니다.  확장자가 달라 기존파일을 덥어쓰지는 않습니다.

 

 

파일이 저장 되었습니다. [OK] 버튼을 클릭 합니다.

 

다시 파일 찾기를 선택해서 변경된 xxx.ppk 파일을 선택해 줍니다.

 

 

키 선택이 완료 되었습니다.  [OK] 버튼을 클릭 합니다.

 

 

선택한 키 정보가 보이지는 않지만 모든 설정이 완료 되었습니다.

이제 [Login] 버튼을 클릭 하면

 

접속하려는 서버에 대한 확인을 하고

 

 

접속이 완료 됩니다.

많은 FTP Client 프로그램이 있지만 많이 사용하는 2개만 알아보았습니다.  다른 프로그램도 비슷하게 설정하면 됩니다.

 

- copy coding -

 

쿼리를 이용하여 DB LINK를 만들기 위한 방법을 기록해 봅니다.
수정할 부분은 아래 두개의 쿼리에 붉은색 내용만 작업 하려는 시스템에 맞도록 수정하면 됩니다.

 

- 연결 서버 생성


EXEC sp_addlinkedserver  
       @server='REMOTEDB_DBLINK',  -- DB LINK할 서버의 별칭. 마음대로 기입.
       @srvproduct = '', -- 공백.
       @provider = 'SQLOLEDB', -- SQL 서버.
       @datasrc = '192.168.0.111', -- DB LINK할 서버의 IP.        
       @provstr='',   -- 공백.
       @catalog='REMOTEDB'   -- DB LINK할 DataBase 명칭.

 

- 연결 계정 생성


EXEC sp_addlinkedsrvlogin

      @rmtsrvname='REMOTEDB_DBLINK',  -- DB LINK할 서버의 별칭. 마음대로 기입.
      @useself= 'false',
      @rmtuser = 'userid', -- 연결할 DB의 계정
      @rmtpassword = 'password12@#' -- 연결할 DB의 계정 비밀번호

 

DB LINK가 완료 되면 링크된 디비를 조회해 봅니다.

 

REMOTEDB_DBLINK.REMOTEDB.dbo.TB_member;

 

대괄호로 묶기도 하는데 결과는 동일합니다.

 

SELECT * FROM [REMOTEDB_DBLINK].[REMOTEDB].[dbo].[TB_member];

 

검색 결과가 나왔다면 성공 입니다.

 

- copy coding -

집에서 Server를 구축하고 외부에서 Server에 접속하는 방법은 여러가지가 있는데 개인적인 생각으로는 제일 간단한 방법이 포트 포워딩(port forwarding) 다른말로 포트 매핑(port mapping)이라고 생각 합니다.  오늘은 가상이 아닌 실제 스마트폰으로 Server 접속 테스트를 해야 하는 상황이 발생 했는데 당연히 localhost(127.0.0.1)로는 핸드폰에서 인터넷에 접속을 할 수 없는 상황이 되어 테스트 환경을 만들게 되었습니다.

일단 컴퓨터에서 웹서버를 만들어야 해서 Spring Boot로 API 서버를 만들었습니다. Web Server에서 사용하는 Port는 프로퍼티에

 

server.port=9999

이렇게 설정 하고 먼저 local에서 접속이 되는지 확인을 해 봅니다.

 

잘 되는군요.  그렇지만 스마트폰에서 안드로이드로 Retsrofit을 이용하여 접속을 시도하면 localhost(127.0.0.1)은 공인 IP가 아니기 때문에 접속을 할 수가 없습니다.  이때 필요한 것이 포트 포워딩을 사용하면 localhost도 공인IP처럼 외부에서 사용할 수 있습니다.

포트 포워딩은 공인IP에 Port를 결합 하여(공인IP + Port) 설정한 포트로 요청이 들어오면 매핑테이블에 있는 내부의 컴퓨터에 포워딩 해주는 방식으로 서비스를 진행 합니다.
그럼 공용IP가 있어야 하는데 집에 인터넷을 사용한다면 공용IP는 최소 하나가 존재하는 것으로 생각하면 됩니다.  공유기의 설정 화면에 들어가면 공유기가 인터넷에 연결하기 위한 외부IP를 가지고 있는데 이것이 바로 공인IP 입니다.

 

 

공유기는 이 외부IP를 이용하여 내부에서 사용할 수 있는 사설IP를 외부와 중개하는 기능을 하고 있습니다. 집에 있는 컴퓨터나 핸드폰의 IP를 확인하면 192.168.0.2 부터 192.168.0.254 까지 중복이 안되는 번호를 하나씩 가지고 있는데 이것이 사설IP 입니다.  공유기는 외부 IP와 내부 IP를 매핑하여 인터넷에 연결해 주는데 이러한 기능을 이용하여 외부IP에 Port를 결합하여 내부IP와 1:1 매핑을 하게 되면 설정한 내부IP는 계속해서 외부와 연결 할 수 있는 통로를 얻게 되는 방법 입니다.


일단 설정을 해보도록 합니다.  집에 ipTime을 사용해서 이걸 기준으로 설명 합니다.  관리자 페이지에 로그인을 하고(초기 아이디와 비번은 admin/admin) 

 

고급설정 > NAT/라우터 관리 > 포트포워드 설정
메뉴를 선택 합니다.

 

 

위에 사진은 생성을 한 모습이고 하단에 입력 해야 하는 항목들 입니다.

 

 

 

 

규칙이름 : 그냥 구분을 위한 텍스트입니다. 아무거나 적어도 됩니다.
외부 포트 : 공인IP 뒤에 붙일 Port 번호 입니다. 임의의 번호를 적습니다.
내부 포트 : 내부에서 구축한 서버에서 서비스할 Port 입니다. 이건 정확히 기입합니다.
내부 IP주소 : 서버를 구축한 컴퓨터의 IP 주소.(이건 뒤쪽에서 설명)

 

입력 값들 중 내부 IP와 포트가 중요합니다.  내부 포트는 Web Server의 서비스 port 를 9999로 했으니 9999를 입력 하면 되고 외부 포트는 임의의 번호를 입력하면 됩니다.  여기서는 나중에 혼란을 주기 싫어 동일하게 9999를 입력하였습니다.
내용들을 채우고 [적용] 버튼을 클릭하면 됩니다.  설정은 이게 끝입니다.


한번 외부에서 브라우저를 통해 접속해 볼까요?  외부 IP에 위에서 설정한 Port 9999를 사용합니다.  localhost:9999/getTest에서 localhost를 외부 IP로 변경해주면 됩니다.

 

 

 

접속이 잘 되는 군요.
이번엔 원래 목적인 스마트폰에서도 똑같이 외부 IP를 사용해 http://210.106.XXX.XXX:9999/getTest 주소로 접속해 봅니다.

 

 

 

이것도 잘 되는 군요. 
설정 방법 중 한가지 아직 설명을 안한게 있습니다.  ipTime 입력 창에서 Web Server로 사용하는 컴퓨터의 [내부 IP 주소] 인 로컬IP를 알아야 합니다.

명령 프롬프트에서


C:\>ipconfig/all


하면 아래와 비슷한(유선을 사용한다면 Ethernet adapter...로 시작) 내용을 찾을 수 있습니다.  저는 Wi-Fi를 사용하고 있어서 무선 LAN 어댑터 Wi-Fi 항목을 보면 됩니다.

 

 

 

여기서 IPv4 주소가 컴퓨터 IP입니다.  이걸 itTime에 입력 하면 됩니다.  컴퓨터를 재부팅 해도 왠만하면 잘 변경이 되지 않지만 확실히 하려면 인터넷 디바이스에 설정을 해놓는게 안전 합니다. 재부팅 되었는데 내부 IP가 변경되면 공유기를 또다시 설정 해야 하는데 모르는 사람만 집에 있으면 참 답답 합니다. 

[네트워크 연결]을 열고

 

 

사용하고 있는 무선 또는 유선의 속성을 선택 하여(저는 Wi-Fi, 유선은 이더넷을 사용) 마우스 우클릭 해서 설정을 선택 합니다.

 

 

 

TCP/IPv4를 선택하고 [속성] 버튼을 클릭 하여

 

 

 

IP 설정 창에서 [다음 IP 주소 사용]을 선택하여 아까 보았던 명령 프롬프트에 있는 서브넷, 게이트웨이, DNS등을 보고 내용들을 채워 넣으면 다음에 컴퓨터가 재부팅 되어도 동일한 IP를 사용하게 됩니다. 
실제 설정은 5분도 안걸리는데 글을 써서 올리는 건 퇴근 후 하다보니 몇일이 넘게 걸리는군요. 집에서 서버를 운용하려는 사람들에게 도움이 되었길 바랍니다.

 

- copy coding -


Serverandroid app간에 데이터를 주고 받는 작업이 필요하여 간단하게 샘플 작업을 해보았습니다인터넷에 많은 예제가 널려 있는데 하나 더 던져 봅니다.  IPPC에 설정된 것으로 사용을 하기 위해 PC에 설정된(자동으로 잡히도록 되어 있으므로 다음에는 변할 수 있지만) 값을 찾아 봅니다.  ipconfig/all 명령으로 찾으면 됩니다.


andriod eclipse socket


 

1. Eclipse Server

 

서버에서는 IP는 사용하지 않고 port 번호만으로 접속 대기 상황을 만들면 됩니다그리고 client에서 연결 요청과 데이터가 들어오면 다시 보내주는 작업을 진행 합니다.

 

//client 접속 대기

Socket client = serverSocket.accept();

//client data 수신

BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

String str = in.readLine();

//client 다시 전송

PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);

out.println("Server Received : '" + str + "'");

 

2. Android Client

 

Client 에서는 화면작업이 좀 있습니다그리고 문자를 입력 받아 서버에 보내주고 다시 받아오는 작업을 진행 합니다.

 

//소켓 생성
InetAddress serverAddr = InetAddress.getByName(ip);
 
socket =  new Socket(serverAddr,port);
//입력 메시지
String sndMsg = et.getText().toString();
//데이터 전송
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.println(sndMsg);
//데이터 수신
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String read = input.readLine();

 

그리고 인터넷을 사용하므로 Manifest.xml에 권한 설정을 해주면 됩니다.

 

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

 

  

3. 결과 화면

 

안드로이드 클라이언트 화면입니다문자 입력과 전송버튼 그리고 서버로 부터 받은 데이터를 화면에 출력하는 기능이 있습니다.


andriod eclipse socket


이런... Connet 버튼은 테스트하려고 만들었는데 사용하지 않습니다삭제 안했네요.

 

서버쪽은 클라이언트에서 보내온 데이터를 콘솔에 출력만 합니다.


andriod eclipse socket


소스가 간단해서 설명도 간단 하네요.

 

4. 전체 소스

 

4.1 Eclipse Server

 

package egovframework.admin.chart.web;

 

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.InputStreamReader;

import java.io.ObjectOutputStream;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

 

public class TCPServer implements Runnable {

 

             public static final int ServerPort = 9999;

//    public static final String ServerIP = "192.168.0.6";

 

             @Override

             public void run() {

                           try {

            System.out.println("Connecting...");

            ServerSocket serverSocket = new ServerSocket(ServerPort);

 

            while (true) {

                     //client 접속 대기

                Socket client = serverSocket.accept();

                System.out.println("Receiving...");

                try {

                   //client data 수신

                    BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

                    String str = in.readLine();

                    System.out.println("Received: '" + str + "'");

                    //client에 다시 전송

                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);

                    out.println("Server Received : '" + str + "'");

                   

                } catch (Exception e) {

                    System.out.println("Error");

                    e.printStackTrace();

                } finally {

                    client.close();

                    System.out.println("Done.");

                }

            }

        } catch (Exception e) {

            System.out.println("S: Error");

            e.printStackTrace();

        }

             }

            

             public static void main(String[] args) {

        Thread ServerThread = new Thread(new TCPServer());

        ServerThread.start();

     }

}

 

4.2 안드로이드 Client

 

activity_main.xml

 

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:app="http://schemas.android.com/apk/res-auto"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
tools:context=".MainActivity">

    <
TextView
       
android:id="@+id/TextView01"
       
android:layout_width="fill_parent"
       
android:layout_height="wrap_content" />

    <
EditText
       
android:id="@+id/EditText01"
       
android:layout_width="289dp"
       
android:layout_height="wrap_content"
       
android:layout_marginStart="92dp"
       
app:layout_constraintStart_toStartOf="@+id/Button01"
       
tools:layout_editor_absoluteY="0dp" />

    <
Button
       
android:id="@+id/Button01"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:text="Send" />

    <
Button
       
android:id="@+id/button02"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_marginEnd="16dp"
       
android:layout_marginTop="456dp"
       
android:text="Connect"
       
app:layout_constraintEnd_toEndOf="parent"
       
app:layout_constraintTop_toTopOf="parent" />

    <
TextView
       
android:id="@+id/chatTV"
       
android:layout_width="fill_parent"
       
android:layout_height="381dp"
       
android:layout_marginTop="64dp"
       
app:layout_constraintTop_toTopOf="@+id/TextView01"
       
tools:layout_editor_absoluteX="0dp" />
</
android.support.constraint.ConstraintLayout>

 

 

AndroidManifest.xml

 

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

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

    <
application
       
android:allowBackup="true"
       
android:icon="@mipmap/ic_launcher"
       
android:label="@string/app_name"
       
android:roundIcon="@mipmap/ic_launcher_round"
       
android:supportsRtl="true"
       
android:theme="@style/AppTheme">
        <
activity android:name=".MainActivity">
            <
intent-filter>
                <
action android:name="android.intent.action.MAIN" />

                <
category android:name="android.intent.category.LAUNCHER" />
            </
intent-filter>
        </
activity>
    </
application>

</
manifest>

 

 

MainActivity.java


package com.example.tcpclient;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;


public class MainActivity extends AppCompatActivity {

   
private Handler mHandler;
    Socket
socket;
   
private String ip = "192.168.0.6"; // IP 주소
   
private int port = 9999; // PORT번호
   
EditText et;
    TextView
msgTV;

   
@Override
   
protected void onStop() {
       
super.onStop();
       
try {
           
socket.close();
        }
catch (IOException e) {
            e.printStackTrace();
        }
    }

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

       
mHandler = new Handler();

       
et = (EditText) findViewById(R.id.EditText01);
        Button btn = (Button) findViewById(R.id.
Button01);
        Button btnCon = (Button)findViewById(R.id.
button02);
       
final TextView tv = (TextView) findViewById(R.id.TextView01);
       
msgTV = (TextView)findViewById(R.id.chatTV);

        btn.setOnClickListener(
new View.OnClickListener() {
           
public void onClick(View v) {
               
if (et.getText().toString() != null || !et.getText().toString().equals("")) {
                    ConnectThread th =
new ConnectThread();
                    th.start();
                }
            }
        });
    }

   
class ConnectThread extends Thread{
       
public void run(){
           
try{
               
//소켓 생성
               
InetAddress serverAddr = InetAddress.getByName(ip);
                
socket new Socket(serverAddr,port);
               
//입력 메시지
               
String sndMsg = et.getText().toString();
                Log.d(
"=============", sndMsg);
               
//데이터 전송
               
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
                out.println(sndMsg);
               
//데이터 수신
               
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String read = input.readLine();
               
//화면 출력
               
mHandler.post(new msgUpdate(read));
                Log.d(
"=============", read);
               
socket.close();
            }
catch(Exception e){
                e.printStackTrace();
            }
        }
    }
   
// 받은 메시지 출력
   
class msgUpdate implements Runnable {
       
private String msg;
       
public msgUpdate(String str) {
           
this.msg = str;
        }
       
public void run() {
           
msgTV.setText(msgTV.getText().toString() + msg + "\n");
        }
    };
}

 

- copy coding -


123

+ Recent posts