소스는 아래 링크에서 받으시면 됩니다.


사용의 예제는 SuperSocket\Delphi\Samples\P2P UDP 폴더에 서버와 클라이언트를 참고하시면 됩니다.


제가 진행했었던 1:1 온라인 강의 시스템에 사용했던 소스 일부를 새로 정리해 본 것입니다.  예전 소스를 거의 무시한채 새로 만들었기 때문에 버그가 많을 수 있습니다.  이슈에 남겨주시면 틈틈히 고쳐 나가겠습니다. 


기본적으로 UDP를 이용해서 P2P로 패킷을 전송하지만, P2P로 보낼 수 없는 상황이되면 TCP를 이용해서 서버를 통해 릴레이를 하게 되어 있습니다.


원래는 1:1 서비스에서 사용했지만 n:m 상황에서도 사용할 수 있도록 수정했습니다.  기본적인 로그인 처리 및 사용자 처리 등의 패킷이 정의 되어 있습니다.

  • 서버
    • UDP 홀펀칭을 위해서 외부 주소 및 포트를 전달하기 위한 게이트웨이 역활
    • UDP 홀펀칭이 실패하면 서버가 TCP로 릴레이로 전달하는 기능
  • 클라이언트
    • 접속, 로그인, 패킷 전송


자세한 사용법은 기회가 될 때 온라인이나 오프라인 강의로 진행하도록 하겠습니다.


예제를 컴파일 하시면 SuperSocket\Bin 폴더가 생기면서 실행 파일 두 개가 생성됩니다.  우선 P2P_Server.exe를 실행하고, Client.exe를 두 번 실행합니다.


Client.exe 실행 화면


  • 상단 왼쪽에 서버 주소를 입력합니다.  
    • 127.0.0.1이 기본 설정되어 있습니다.
  • Room-01에 방 이름을 입력합니다.  
    • 동시에 여러 강의실(대화실)을 개설하기 위해서 사용했습니다.  
    • 저는 실적용에서 랜덤한 긴 문자열을 사용했습니다.
  • User-A에 사용자 아이디를 입력합니다.
    • 암호 처리는 서버 소스를 참고해서 추가하셔야 합니다.
    • 같은 방에 같은 아이디로 접속하면 기존의 아이디가 로그아웃 됩니다.  이를 클라이언트에서 신호를 받아 접속을 끊어야 하는데, 지금보니 해당 처리가 빠져있네요.  다음 커밋에서 추가하도록 하겠습니다.
  • Connect 버턴을 클릭하고, Login 버턴을 클릭하면 됩니다.
  • 가장 긴 빈 에디터에서 메시지를 입력하고 리턴하면 접속 된 사용자에게 모두 메시지를 보냅니다.
  • Start 버턴을 누르면 연속되는 숫자를 계속 보냅니다.  혹시 하나라도 누락이 되면 현재 숫자가 표시됩니다.  
    • UDP로 원격지에서 오는 메시지가 얼마나 사라지는 지 확인하기 위해서 테스트로 만들었습니다.
  • 사용자 입장 및 퇴장 그리고 목록 보이기 등의 기능이 구현되어 있지만, 예제에 완전히 표현되지 않았습니다.  다음 커밋에 추가하도록 하겠습니다.



저작자 표시 비영리 변경 금지
신고

Posted by 류종택



자주 쓰는 형태인데, 매번 스래드 안에서 PostMessage를 날려서 사용하다보니 불편해서 유닛으로 만들었습니다.


사용법은 아래와 같습니다.

procedure TfmMain.FormCreate(Sender: TObject);
begin
  AsyncTask(
    // This will execute task asynchronously by new thread without blocking.
    procedure (AUserData:pointer)
    begin
      Sleep(1000 * 3);
    end,

    // This will execute by main thread after above code completed.
    procedure (AUserData:pointer) 
    begin
      fmMain.Caption := 'Done';
    end
  );
end;

AsyncTask() 함수는 두 개의 익명함수가 필요합니다.  첫 번 째 함수는 별도의 스레드에 의해서 비동기적으로 실행됩니다.  그리고, 실행이 끝나고 난 뒤에는 두 번 째 익명함수가 실행됩니다.  두 번 째 익명함수는 메인 스래드에서 실행되기 때문에 UI 접근을 해도 문제가 되지 않습니다.


AUserData는 AsyncTask(익명함수, 익명함수, UserData) 와 같이 마지막 인자로 넘겨준 포인터 값입니다.  생략하면 nil이 됩니다.


소스는 아래의 링크를 참고하시기 바랍니다.






저작자 표시 비영리 변경 금지
신고

Posted by 류종택


이름을 보면 언뜻 "와!  엄청난 소켓이구나!!"하는 느낌이 팍 올 겁니다.  하지만, 낚이셨습니다 ㅡ.ㅡ;;  이 소켓 라이브러리의 이름은 "제발 잘 돌아가라!!!"라는 염원에서 시작한 것일 뿐입니다 ^^;


그래도, 5년차에 접어드는 서비스의 핵심(?) 라이브러리이기도 합니다.  현재까지 별 사고 없이 안정적으로 운영되던 소스였으나, 너무 오랫 동안 초기 설계를 간직하고 있는 탓에 서비스의 전체 코드를 다시 작성하고 있습니다.  Super Socket은 그 중 일부분입니다.  서비스에 사용된 소스는 잡스러운 군더더기가 많았기 때문에 처음부터 새로 작성하였으며, 아직 따끈한 상태에서 공개합니다.  (버그가 상당히 잠재.. 음...  최대한 간결한 기능을 갖추도록 노력하였습니다)


이 소켓 라이브러리는 범용적이지는 않기 때문에 다른 분들에게 도움이 되지 않을 수도 있습니다.  장점이라면, 제가 서비스를 유지.보수하는 동안 지속적으로 업데이트 될 것이라는 점입니다.


서비스에 사용 중인 버전은 윈도우, 안드로이드, iOS 세 개의 플랫폼 용이 있으나, 현재는 윈도우용만이 새로 만들어졌습니다.  윈도우 플랫폼에서 테스트가 완료되면 안드로이드, iOS 그리고 맥 순으로 추가 할 예정입니다.  (전체 서비스를 새로 만들고 있기 때문에 시간이 오래 거릴 것입니다)


소켓의 특징이 있는데,

  • 패킷 크기가 2048로 고정되어 있습니다.  이보다 큰 패킷을 조각내서 보내고 받는 쪽에서 합쳐서 사용하고 있습니다.  (상수를 수정해서 변경 할 수는 있습니다)
  • 최대 컨넥션은 4096개입니다.  (상수를 수정해서 변경 할 수는 있습니다)
  • 패킷은 [해더]  [패킷타입]  [데이터] 형태로 주고 받습니다.
  • 해더는 2바이트이며, 상위 4비트는 Direction이라는 개인 용도로 사용하고 있으며, 이는 다른 용도로 사용해도 무방합니다.  나머지 12비트는 데이터의 크기입니다.
  • 레거시 서버 소켓 코드에서는 워커 스래드가 내부에서 동작하였으나, 새로 작성 할 때 싱글 스레드로 변경하였습니다.  패킷이 수신 된 이후에는 외부에서 워커 스래드를 만들어서 사용하고 있습니다.

소스 코드는,


예전에 공개한 화상 강의 오픈 프로젝트를 통해서 사용법을 추가하도록 하겠습니다.  진행 속도는 항상 그래왔듯이 상당히 늦을 것 같습니다. ^^*

저작자 표시 비영리 변경 금지
신고

'RyuLib > Super Socket' 카테고리의 다른 글

Super Socket - 소켓 라이브러리  (0) 2016.09.22

Posted by 류종택
  • "Intel Media SDK"를 이용한 H.264 인코딩과 디코딩 라이브러리 입니다.
  • YUV 변환을 위해서 "Intel Parallel Studio"를 사용하였습니다.  libyuv 같은 오픈 소스를 사용하셔도 됩니다.
  • 화상회의나 아프리카 TV와 같은 어플리케이션을 작성하시려는 분들에게 참고가 될 것 입니다.

소스코드는 https://github.com/ryujt/IntelEncoder 에서 다운 받으실 수 있습니다.

폴더 구조

  • Src/IntelEncoder
    • Visual C++ 을 이용하여 DLL로 만들어진 라이브러리 소스입니다.  (IntelEncoder.dll)
  • Samples/Delphi/01. Basic Demo
    • C++로 작성 된 IntelEncoder.dll 를 이용하는 가벼운 예제입니다. 
    • 예제는 아직 델파이 버전만 작성하였습니다.
    • 화면의 (0, 0) - (1280, 720) 영역을 H264로 인코딩하고 이것을 다시 디코딩해서 프로그램 화면에 표시하는 예제입니다.


아래는 델파이로 만든 Basic Demo 실행 파일입니다.

Bin.zip



저작자 표시 비영리 변경 금지
신고

'RyuLib > Intel Encoder' 카테고리의 다른 글

Intel H.264 Encoding and Decoding  (0) 2016.07.10

Posted by 류종택

바쁜 와중에 주말에 소스 분석 프로그램을 만들어 봤습니다.  기능은 별로 없는 데 시간은 많이 잡아 먹네요 ㅠ.ㅠ

  • 클래스의 메소드의 begin 뒤에 디버깅 코드를 삽입하는 프로그램입니다.
  • 소스를 분석 할 때, 단일 이벤트가 어떤 경로를 거치는 지 확인하고 싶을 때 사용합니다.
  • 디버깅 모드로 소스를 차근 차근 들어가다보면, 객체의 실행 코드가 아닌 추상화 래벨의 코드로 넘어가서 분석을 귀찮게 할 때도 사용합니다.
  • Config.pas에서 삽입 할 디버깅 코드와 유닛을 지정 할 수 있습니다.

저장소 위치: https://github.com/ryujt/ryulib4delphi/tree/master/Projects/InsertDebugCode


[실행 화면]


  • Execute 버턴을 클릭합니다.
  • 소스가 있는 폴더를 선택합니다.
  • 확인 버턴을 클릭합니다.
  • 선택 된 폴더 및 하위 폴더를 검색하여 모든 *.pas 파일에 디버깅 코드를 삽입합니다.
  • 테스트 케이스로 사용 된 코드가 있는 TestFile 이라는 폴더가 디폴트로 선택 됩니다.  확인 버턴을 클릭하면, 해당 소스가 어떻게 바뀌는 지 확인 하실 수가 있습니다.


주의!!

  • 복구 기능이 없습니다.  복사본을 이용하시거나 소스 버전 관리 프로그램을 이용하세요.
  • 코드 삽입에 대한 필터링은 Config.pas의 DebugCodeMethodBegin 함수에서 AMethodName을 참고하여 Result := '' 처럼 하시면 됩니다.
  • 일반 함수나, 인라인 함수 등은 무시합니다.
  • 컴파일러 지시자를 처리하지 않고 있기 때문에 컴파일러 지시자에 따라 파싱 에러가 발생 될 수 있습니다.  현재는 메소드 마지막에는 디버깅 코드를 삽입하지 않도록 코멘트 처리하였습니다.


저작자 표시 비영리 변경 금지
신고

Posted by 류종택




권한 상승 중인 프로그램에서 권한이 낮은 상태로 프로그램을 실행시키는 방법입니다.  구글링을 통해서 주어 온 소스가 제대로 동작하지 않아서, MSDN을 오가며 약간의 삽질을 하였습니다.  저처럼 불필요한 삽질을 하시게 될 분이 있을 지 몰라서 올려봅니다.


소스는 아래 링크를 참고하시면 됩니다.


사용법은 단순합니다.  위의 유닛에 있는 아래의 함수를 실행하면 됩니다.

  • procedure CreateLowProc(ACommandLine:WideString);
    • ACommandLine 에는 실행시킬 프로그램 파일명을 입력하시면 됩니다.  파라메터가 필요한 경우에는 붙여서 사용하시면 됩니다.
    • 예: CreateLowProc( 'notepad.exe Test.txt' );


저작자 표시 비영리 변경 금지
신고

Posted by 류종택

하마티(http://www.himytv.com/) 안드로이드 버전을 만들 때, 델파이 코드 중에 열거형을 자바로 바꾸기 위해서 만든 프로그램입니다.


소스는 아래 링크를 참고하시면 됩니다.  상당히 단순한 프로그램입니다.


프로그램 동작은

  • 델파이 열거형의 소스의 일부분을 붙여 넣고, Convert 버턴을 클릭합니다.
  • 열거형의 원소들은 자바의 static으로 변경됩니다.
  • toString() 이라는 static 메소드가 추가 됩니다.  열거형을 문자로 표현하고 싶을 때 사용합니다.  제가 델파이에서 디버깅 등을 이유로 자주 사용하는 것이라 넣어 봤습니다.
  • 델파이 소스에 있는 코멘트는 모두 제거 됩니다.
  • 열거형 원소에 인덱스를 강제로 지정하는 등의 처리는 지원하지 않습니다.

[그림 1] 변경 전의 델파이 소스



[그림 2] 변경 후의 자바 소스




저작자 표시 비영리 변경 금지
신고

Posted by 류종택

프로그래밍 소스 코드를 스캐닝하고 싶을 때 사용 할 수 있는 유닛입니다.  스캐닝 후 공백 등의 화이트 스페이스와 코멘트는 무시하고, 특수문자(ttSpecialChar), 문자열(ttString), 숫자(ttNumber), 식별자(ttIdentifier)를 찾아 줍니다.  제가 예전에 계산기 및 프로그래밍 언어를 만들 때 사용하던 것입니다.


소스보기: http://goo.gl/Ucev3A



사용법

procedure ....;
var
  Scanner : TScanner;
  Token : TToken;
begin
  Scanner := TScanner.Create;
  Scanner.SetText( '소스코드...' );

  repeat
    Token := Scanner.GetNextToken;

    if Token.TokenType = ttString then
      WriteLn(
        Format('* %4d:%3d - ''%s''', [Token.Line, Token.Col, Token.Text])
      );
  until Scanner.IsEOF;
  ...
end;

7: SetText 메소드를 이용해서 스캐닝하고자 하는 소스코드 내용을 입력합니다.

9-16: 소스 코드의 끝까지 검색하면서 반복합니다.

10: GetNextToken 메소드는 현재 위치 이후의 토큰을 찾아 줍니다.

12-15: 찾아낸 토큰(TToken)에는 소스 내의 라인 위치 및 토큰의 타입 등을 알 수가 있습니다.



기타

  • property PascalStyle : boolean (read / write)
    • 파스칼 코드를 스캐닝 할 때는 true로 설정되어 있어야 합니다.  false라면 C 언어 스타일이 됩니다.
  • property UseStringEscape :boolean (read)
    • C 언어 스타일이 되면, 문자열 내에서 Escape 문자 처리가 됩니다.






저작자 표시 비영리 변경 금지
신고

Posted by 류종택

우선 전체 소스는 http://goo.gl/0dSTvu 에 있습니다.  RyuLib for Delphi 저장소에 있는 라이브러리가 필요하니 전부 받으시는 것을 좋을 듯 합니다.  (https://code.google.com/p/ryulib4delphi/)


[그림 1] 실행 화면


웬지 이런 프로그램이 있을 거 같지만, 검색도 잘 못하는 컴맹인지라 그냥 만들어서 쓰기로 했습니다 ㅡ.ㅡa



사용법은 간단합니다.


C:\> ExtractStrings.exe  [Path] [File Ext]  -r

  • Path: 검색 할 경로, 생략하면 뒤에 오는 [File Ext]도 생략해야 합니다.  마음에 안드시면 소스를 수정하세요 ㅋㅋ  생략하면 현재 경로를 검색합니다.
  • File Ext: 검색 할 확장자.  *.pas 처럼 하시면 됩니다.
  • -r 또는 -recursive: 하위 폴더들을 모두 검색하게 됩니다.
소스는 파스칼 언어 스타일에 맞도록 되어 있습니다.  소스 중에 문자열이 있으면 모두 화면에 표시해 줍니다.


빌드하시기 싫으신 분들을 위한 실행파일 서비스 ^^*


주요 소스 설명
  • SearchDir.pas
  • Scanner.pas  (http://ryulib.tistory.com/344)
    • 프로그래밍 언어에 대한 스캐너.
    • 디폴트로 파스칼 언어에 맞춰져 있습니다.  코멘트 및 문자열 처리가 다릅니다.
    • property PascalStyle 를 false로 세팅하면 C 언어 스타일이 됩니다.
    • 소스보기: http://goo.gl/Ucev3A





저작자 표시 비영리 변경 금지
신고

Posted by 류종택

일단 사용법을 먼저 보겠습니다.

package com.example.chatmessagetest;

import ryulib.ChatControl.ChatView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {
	
	private ChatView _ChatView = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		_ChatView = new ChatView(this);
		_ChatView.setLeftBackgroundImage(R.drawable.left_message_bg);
		_ChatView.setRightBackgroundImage(R.drawable.right_message_bg);
		
		setContentView(_ChatView);
		
		_ChatView.addLeftChatMessage("You", "Hello?\nHow are you?");
		_ChatView.addRightChatMessage("Her", "Hi!");
	}

}


소스가 간단합니다.  일단 카카오톡과 같은 방식으로 왼쪽 오른쪽으로 나눠서 채팅이 오가는 컨트롤입니다.  


이미지를 만들 능력이 없어서 인터넷에서 내려 받아서 테스트했기 때문에 이미지를 포함하지는 못했습니다.  이미지는 ninepatch로 작성되어야 합니다.

  • R.drawable.left_message_bg: 왼쪽 말 풍선 이미지
  • R.drawable.right_message_bg: 오른쪽 말 풍선 이미지


addLeftChatMessage, addRightChatMessage 두 메소드는 파라메터를 두 개 지정해야 합니다.  첫 번 째 것은 사용자의 이름 또는 아이디를 의미하고 두 번 째가 메시지 내용입니다.


컨트롤의 실제 소스는 아래 파일을 참고하시기 바랍니다.   (제 구글 오픈소스 저장소가 오늘 말썽이라서 파일로 올립니다)


ChatControl.zip


추후 프로젝트 중에 업데이트가 있으면 http://goo.gl/1l71Z9 이곳에 올려두겠습니다.  아직은 사용 할 지 안 할 지도 미지수 ^^;


저작자 표시 비영리 변경 금지
신고

Posted by 류종택


티스토리 툴바