네트워크 프로그램 버전호환성

hermian의 이미지

네트워크 프로그램에서 서버와 클라이언트가 구조체로 데이터를 주고 받고 있습니다.
대략 구조체의 모양은 아래와 같습니다.
typedef byte unsigned char;
struct _A {
byte a[MAX_A];
byte b[MAX_B];
} A;

위 모양의 구조체를 서버와 클라이어트가 주고 받고 있는데 만약, 차기 버전에서 MAX_A값이 바꾼다면 이 구조체를 주고 받는 서버와 클라이언트 간에 버전 호환성이 유지 되지 않습니다.
즉 서버는 1.1버전-MAX_A가 바뀐- 이고 클라이언트는 1.0버전이라면 문제가 됩니다.
여러분은 이러한 네트워크 프로그램의 문제점을 어떻게 해결하시는지요?
(단, 구조체는 약식이며 실제 구조는 훨씬 복잡합니다.)

------------------------------------------------------
client가 모종?의 서비스를 수행중인데 안정성을 검증하기 위해 10개중 5개는 이전 버전으로 나머지 5개는 신버전으로 운용해야 합니다.
이 안정성이 검증된 이후에야 모든 client를 신버전으로 업데이트합니다.
따라서 자동 업데이트는 안됩니다. :oops:

이런 시나리오로 진행되기 때문에 제가 원하는 종류의 답은 구조체를 어떻게 기술적으로 잘 정의 하는 방법이나 아니면 새로운 프로토콜?이 있느냐 하는 거죠.

IPv4와 IPv6처럼 복잡한 경우는 아니지만 (그렇다고 중간에 변환할 수 있는 어플은 절대 넣을 수 없는 상황입니다.) 워낙 정적인(정해진) 데이타를 주고 받는 경우라서요.. 점점 질문이 늘어나는군요 ^^;; 이것으로 제가 원하는 질문이 될런지(질문이라는게 적어보니 힘들군요) 답변 고맙습니다.

cpulpul의 이미지

Client 에서 Server로 data송/수신시..

서버의 버전을 확인후..

서버의 버전에 맞게 DATA변환후...

송/수신작업을 하면 문제 없을듯 합니다...

천재태지서주영의 이미지

꼭 그런 이유는 아니겠지만 nateon 메신저를 사용하면 자주 그런 현상을 목격하죠.
메신저 실행시마다 신버전 체크를 하는데 메신저가 며칠마다 업데이트 되더라구요 ㅡ_ㅡ;
개발자 분들이 참 부지런하신것 같아요.. %^^%

결론적으로 interrupt 님께서 하신 말씀이 좋은 방법 같군요.

천재태지서주영

hermian의 이미지

Client 에서 Server로 data송/수신시..

서버의 버전을 확인후..

서버의 버전에 맞게 DATA변환후... 

Client버전이 높다면 되지만 낮은 경우는 어떻게 변환하나요?
게임에서 이런 것에 대해 노하우가 많을 듯 한데...^^
천재태지서주영의 이미지

hermian wrote:
Client 에서 Server로 data송/수신시..

서버의 버전을 확인후..

서버의 버전에 맞게 DATA변환후... 

Client버전이 높다면 되지만 낮은 경우는 어떻게 변환하나요?
게임에서 이런 것에 대해 노하우가 많을 듯 한데...^^

음.. 제가 정확하게 글을 안봤네요 ㅡㅡ;
버전이 안맞으면 Data 를 수정할 게 아니라 무조건 Client 측을 업데이트 하도록 하면 되지 않을까요?
예를 들어서 '새 버전이 나왔습니다. 업데이트를 하셔야만 사용하실 수 있습니다. 업데이트를 하시겠습니까?' 와 같은 창을 띄우도록 하는거죠.
온라인 게임에서도 많이 쓰이는 방법이죠. 위에 언급한 메신저에서도 쓰이고 활용을 한다면 여러모로 유용한 방법이겠네요.

물론 서버와의 간단한 작업으로 업데이트가 가능하게 Auto Update 혹은 Auto Patch 기능(V3 에서는 Smart Update 라고 하죠) 을 사전에 구현하셔야겠죠 ^^

천재태지서주영

hermian의 이미지

제가 요구사항을 좀 명확히 하지 못했군요.
여기서 말하는 client는 Embeded시스템으로 쉽게 Auto Update를 할 수 없다는 조건이 있습니다. ^^;;
Server는 Unix or linux 시스템이구요.

펑키의 이미지

안녕하세요.

서버와 클라이언트 버전을 맞추는것은 필수적입니다.

1. 최초 실행시 서버로부터 리스트 파일 다운로드
2. 리스트 파일과 클라이언트의 파일들 비교, 이때는 여러가지 방법이 있으나 저의 경우에는 MD5 HASH를 이용해 비교합니다. 즉, 리스트 파일에 그러한 HASH가 존재하고 클라이언트 측에서는 자신의 로컬에 있는 파일들의 HASH를 실시간 생성하면서 비교합니다. 날짜나 사이즈를 가지고 해도 되지만 이때는 에러율이 상당히 높습니다. (제가 이것 저것 다 해봤거든요.)
3. 변경된 파일 다운로드
4. 실행.

그런데 C/S 버전 맞추는것은 생각외로 고려해주어야할 것이 정말 많습니다. C/S버전 맞출때 변경된것만 비교할것인지 모두다 비교할것인지 등등 많습니다. 왜냐면 클라이언트 로컬쪽에 파일이 손상되었는데 서버측에서 그 정보를 주지 않으면 새로 설치 하지 않는 이상 실행이 불가능하죠. 대신에 그 검색하는 시간이 조금 걸립니다. 저의 경우 800개(P700에서)를 체크 하는데 약 15초 정도 걸립니다.

가변적인 전문이라고 해도 다른 방법으로 해결 할려고 하면 결국에는 문제에 봉착할듯 싶습니다. 예를 들면 HEADER+BODY로 구조체를 통째로 만들어 써도 나중에는 BODY부에 몇번째 바이트가 무엇 하는 식으로 말이죠.

제가 업데이트시 사용하는 방법은..

1. 메인 서버에 접속하여 업데이트 정보가 있는 정보를 전문으로 요구
2. 업데이트 정보가 있는 정보(IP, PORT, 접속 방식 등등)를 전문으로 응답
3. HTTP를 이용한 리스트 파일 다운로드
4. 리스트 파일의 MD5 HASH를 이용해 로컬의 파일들과 비교.
5. 바뀐 HASH가 있으면 다운로드(HTTP)
6. 실행

이때 한가지 업데이터하는 프로그램을 업데이트 하는 루틴도 추가 되어야 할것입니다. 이부분이 조금 고민될수도 있습니다. 에구 어디 가야 되서 요기 까지만.....

simpid의 이미지

서버와 클라이언트간이 통신을 위해 만들어진 프로토콜은 일단 배포가 되면 바꿀 수 없다는 전제가 필요하다고 생각합니다.

님께서는 프로그램 버젼이 1.0, 1.1, 1.2.... 등등으로 올라갈 수록 구조체등이 바뀔 수 있다고 생각하시는것 같은데 그러면 안됩니다.

정의된 프로토콜은 무조건 바뀔 수 없고, 처음 프로토콜을 정의 할때 확장이 가능하도록 설계해야 할 것 같습니다.
프로그램 버젼이 올라가서 새로운 기능이 필요하다면 프로토콜을 확장해서 새로운 기능은 새로운 방법으로 통신하고, 기존 기능은 기존의 방법으로 동작해야 할 것 같습니다.

펑키의 이미지

안녕하세요. 우선 글의 내용을 다 읽어 보고 대답을 드리면 제가 생각하
는 범위내에서는 그러한 방법은 현실적으로 존재하지 않을것입니다. 몇가
지 말씀 하신분의 생각을 정리 해보면

1. 프로토콜이 변경될수 있는다는 가정
2. 자동 업데이트는 않된다.

이러한 방법을 해결할수 있는 방법이 있을까요.? 제 생각에는 그렇지
않을듯 싶습니다. 1/2번 둘중에 한가지는 그 반대가 되어야 가능한
해결책인듯 싶습니다. 제가 가장 관심 갖는 분야가 이러한 자동화 부분
인데 저도 몇번 생각을 해보았는데 방법이 없드라구요.

>client가 모종?의 서비스를 수행중인데 안정성을 검증하기 위해 10개중
>5개는 이전 버전으로 나머지 5개는 신버전으로 운용해야 합니다.
>이 안정성이 검증된 이후에야 모든 client를 신버전으로 업데이트합니다.
>따라서 자동 업데이트는 안됩니다.
안정성 검증은 테스트용 클라이언트와 서버가 별도로 존재하는게 일반적
일듯 싶습니다. 저의 경우에는 클라이언트가 4가지 버전이 존재합니다.
물론 서버는 동일한 서버이지만 각각의 프로토콜에 따라 동작하도록 되어
있습니다. 그래서 테스트 서버에 접속하는 테스트 클라이언트를 식별할수
있는 구조를 만들어 놓았습니다.

>이런 시나리오로 진행되기 때문에 제가 원하는 종류의 답은 구조체를 어떻게
>기술적으로 잘 정의 하는 방법이나 아니면 새로운 프로토콜?이 있느냐 하는
>거죠.

만약 구조체로만 한다면 분명 동적인 구조의 할당이 힘들듯 싶습니다. 당연히
구조체 자체가 하드 코딩이 될것이고 하드 코딩된 구조가 만약 변경되어야
하는 상황이 온다면 파일(하드 코딩된) 분명 다운로드 되어야만 할것입니다.

저의 경우에는 이러한 프로시져는 똑같지만 그러한 구조를 외부로 빼놓고
사용합니다. 따라서 관리자들이 직접 그러한 부분을 에디팅 할수 있게 해놓
았습니다. 물론 두가지 방법 모두 업데이트라는것은 이루어져야 합니다.

>IPv4와 IPv6처럼 복잡한 경우는 아니지만 (그렇다고 중간에 변환할 수 있는
>어플은 절대 넣을 수 없는 상황입니다.) 워낙 정적인(정해진) 데이타를 주고
>받는 경우라서요.. 점점 질문이 늘어나는군요 ^^;; 이것으로 제가 원하는
>질문이 될런지(질문이라는게 적어보니 힘들군요) 답변 고맙습니다.

워낙 정적이라는 개념이 모호합니다만 제가 생각하기에는 99.9% 변경이 않된
다고 해도 0.1%의 변경이라도 적용은 되어야 할듯 싶습니다.

다른분이 말씀 하신것 처럼 전송 프로토콜은 절대 변경이 되어서는 않된다는
저의 경우에는 언제든지 변경될수 있고 또 변경이 될수 있도록 허용해주어야
한다로 생각하고 있습니다.

다시 한번 몇번의 가정을 해보면

1. 구조체가 개별 필드 단위로 정의 되어 있다. (크기 고정)
2. 구조체가 뭉뚱그려서 HEADER + BODY + TRAILER 정도로만 구분되어있다.(크기 가변)
3. 필드의 단위를 구분자를 두고서 구분한다.

만약 이정도의 가정만 해놓고 보아도 2/3번 정도가 유력할듯 싶지만 3번째 필드
의(구분자로 구분할 경우)값이 사용자 이름에서 사용자 ID로 바뀌게 된다면 최초의
가정에서 해결할 방법이 없을듯 싶습니다.

그런데 이러한 경우는 있습니다. 조금 후진 방법이긴 하지만 가능한 필드의 구조를
미리 다 정의해 놓는 것입니다. 2/3번 방법을 동시에 섞어서 사용하는 것인데 FIX 혹은
SWIFT방법으로 개별 필드에 필드 번호가 존재합니다. 이것이 가능한 모든 필드를 다
정의 해 놓는 다면 데이터의 위치나 크기에 상관없이 전송이 가능할것입니다. 다만
단점이라면 가능한 모든것을 모두 정의해 놓아야한다는 것입니다.

제가 사용하는 프로토콜은 FIX를 제가 사용하기 쉽게 약간 바꾸어서 사용합니다.

[1=FIX.4.32=8983=04=A5=30147=15=20030611-14294131=20030611-142942153=154=155=0000
58=61=1001=DDDDADEFN1002=00000000000000000093=21301772f65848e46eba184bdeb7b216
89=90=10=]

이런식이죠.

각각의 필드를 보면
이중 1번이라는 것은 프로토콜의 이름을 정의한것이고 그 값은 FIX.4.3 이라는 것입니다.
이것을 DTD나 SCHEMA같은 것을 이용해 정의해 놓았습니다.

이 프로토콜의 장점은 프로토콜의 크기에 상관없습니다. 또한 필드의 위치에 상관이 없습니다.
프로토콜 검증을 자동화 할수 있습니다. 그래서 이러한 방법을 말씀 하신분이 사용하셔도 좋을
듯 싶지만 문제는 이미 정의해 놓은것이 만약에라도 추가 되거나 할 경우가 문제가 아닐까
생각됩니다.

도움이 되시길....

아까 급하게 나가는 바람에 제대로 쓰질 못했네요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.