clnt1 -> (svr) -> clnt2 이렇게 하려면 어떤 방식이 좋을

indizarm의 이미지

-질문
1. socket을 사용하는 상대방이 'write block'되어 있는지
알 수 있습니까?
2. 다음의 x 같은 상황을 어떻게 바꾸어야 '원하는대로' 동작할까요?
(clnt를 send와 recv를 처리하는 쪽으로 분리해야 할까요?)

-원하는 것
1. clnt는 svr를 통해 다른 clnt를 지정해서 메세지를 전한다.
2. 각 clnt에는 ID가 주어진다.
3. 각 clnt는 ID와 socket, IP 주소로 구분된다
4. 각 cnlt의 정보는 table에 저장된다.
더하기. 최소의 process

-현재 상황
1. svr와 clnt 의 형태
____svr: single process. select type. blocking socket
____clnt:single process. blocking socket

2. 동작
____svr: 최초 접속한 clnt는 table에 저장.
_______clnt로부터 메세지를 (1) 받고 (목적지 정보 포함)
_______clnt가 지정한 '목적지'로 받은 메세지를 (2) 전달한다.
_______clnt의 메세지가 'exit'이면 clnt와의 연결을 끊는다.
____clnt:최초 접속시 svr에게 자신의 ID를 알리고
_______연결 수락을 기다린다.
_______연결이 되었으면, '목적지(자신을 포함한 다른 clnt)를
_______맨 앞에 집어넣은 '메세지'를 svr에 (1) 보내고
_______svr로부터 다른 메세지를 (2) 받는다.
_______자신이 입력한 메세지가 'exit'이면 프로그램을 종료한다.

-문제점

1. 연결된 상황에서 각 clnt는 메세지를 보내려는 상황(1)에서 block되어 있다.
2. clnt_1에서 clnt_2로 'clnt_2 $$$' 이런 메세지를 입력한다.
3. (2와 동시에) clnt_2는 메세지를 보내려는 상황(1)에서 block되어 있다.
4. clnt_2에서 (아무 곳으로) 메세지를 보낸다
5. (당연히) clnt_1이 clnt_2에게 보낸 메세지는 날아갔다.

-삽질 유발 아이디어

1. socket을 non-blocking으로 만든다. => 단순히 return만 하게 될 듯.

bugiii의 이미지

클라이언트는 서버에 접속하고 클라이언트의 메시지를 서버가 해석해서 다른 클라이언트로 전달하는 것이 맞습니까? 그렇다면 채팅 서버와 구조가 비슷한 것인가요?

indizarm의 이미지

음... -_-;;

그러고 보니 채팅 서버와 같은 역할이군요.

clnt를 두 개 이상의 process로 분리하지 않고
처리할 수 없을까요?

아, clnt도 select로 반응해야 하는 것인가요? -_-;;

What a Cool Days!!!

bugiii의 이미지

클라이언트 접속마다 새로운 프로세스로 동작하는 서버는 클라이언트의 접속간의 정보 공유가 필요없는 경우에 많이 쓰이는 기법으로 알고 있습니다. 예를 들자면 웹, ftp 같은거... 이런 것은 접속 클라이언트끼리 서로 상관없는 거니까 독립적으로 움직여도 될 것입니다.

하지만 채팅 서버는... 요게... 접속된 클라이언트의 접속 정보들을 프로세스 간에 서로 알아야 하기 때문에 프로세스 모델로 서버를 작성하기는 힘들 것입니다.

그래서, 쓰레드 기법을 쓰거나 select + non-blocking 소켓 기법을 사용하게 되는데... 이것도 좀 골치 아픈 경우가 많습니다. 쓰레드 기법은 동기화에 무지하게 골치를 아프게 하고 select + non-blocking 기법은 그 상태의 저장과 분기에 무지하게 골치가 아프게 됩니다.

그래서 적당한 선에서 타협한 것이... pth 같은 사용자 레벨 쓰레드 라이브러리구요... 저는 요걸 추천합니다. 쓰레드간 전환을 예측할 수 있다는 점에서 동기화에 대한 부담을 아주 아주 많이 덜어주고 (물론 pth 에서도 동기화가 필요한 경우도 있습니다.), 특히 이벤트 (소켓 메시지 등) 기반의 서버에는 딱 알맞은 것 같습니다. 물론 pth 는 성능에는 별로 관심이 없는 라이브러리라 state-thread 같은 라이브러리보다는 속도적인 최적화는 별로 없습니다만 쓰기에 그리 나쁜 것만은 아니었습니다.

그럼, 이만...

indizarm의 이미지

자세한 답변 감사드립니다.

프로그램을 돌릴 환경이 상당히 열악하기 때문에
여러 개의 쓰레드나, 프로세스를 만들기는 힘들듯
하고요 (-_-;; ) 우선은 clnt쪽에서 select로 삽질
을 해보기로 했습니다.
'불가능하다'라는 판단이서면, bugiii님께서 말씀
하신대로 pth 라이브러리를 사용해볼까 합니다.

즐거운 오후되세요. ^_^

아, pth 라이브러리는 (pthread_xx 이런 함수들로
이루어진 것 말씀하시는 것이겠죠?)

What a Cool Days!!!

bugiii의 이미지

pthread 하고는 틀리구요... GNU 의 pth 입니다. (pthread 의 소스레벨 호환을 위한 api 는 있습니다.)

http://www.gnu.org/software/pth

에 있구요. 예제가 좀 약하긴 하지만서도... 해보시면 금방 익히실 수 있을 것입니다. 물론 쓰레드에 대한 기본 지식은 조금 필요하구요. 일반적으로 얘기하는 커널에서 제공하는 (이말이 논란이 되기는 싫습니다. 전에 어떤 게시물에서 한번 난리가 나서...) 쓰레드하고는 성질이 틀리므로 조금 생각이 필요할 수도 있습니다.

select 는 잘 쓰면 참 좋긴한데 (자신만의 뭔가가 있다면... 하지만 이걸로 어느정도 규모가 되어버리면 저같이 머리 나쁜 사람은... 좌절...)... 사실 pth 같은 라이브러리도 select 를 내부에서 감싸고 사용자는 일반적인 흐름으로 프로그래밍을 할 수 있도록 도와주는 것이라 성능상의 차이가 아주 크게 나지는 않을거라고 봅니다. (이건 해당 분야에 적용시켜 보아야 알겠죠) 그리고, 일반 쓰레드와는 달리 pth 쓰레드는 비교적 가볍습니다.

예를 들자면

pth_read 이런 함수를 쓰면 일반 read 처럼 동작을 하지만 내부적으로는 다른 쓰레드에게 컨트롤을 넘길 수 있는 기회를 만들어 줍니다. 즉 쓰레드 컨텍스트 전환을 예측할 수 있다는 것이죠. 그리고 각 동작별 타임아웃을 손쉽게 사용할 수 있다는 장점도 있습니다. 보통의 선점형 멀티쓰레드라면 어디서 쓰레드간 전환이 일어날지 모르므로 구문이나 특정 블럭을 보호하기 위한 동기화 객체가 난무하고 언젠가는... 자기 자신도 이걸 왜썼는지 왜안되는지도 모르는 상태가 되는 경우가 많았습니다.

단점은... 커널쪽에서 보자면 :oops: 단일 쓰레드이므로 SMP 의 장점을 활용할 수 없다는 것이지만 이것이 동기화에 드는 비용과 작업 생산성을 따지고 본다면 비교할 수는 없다고 봅니다. 또 SMP 라고해서 꼭 나머지 CPU 들이 놀고 있지는 않겠죠. 실질적인 io 같은 것은 저 아래단에서 작업을 분배해주리라 믿습니다.

근데, pth 를 실제 응용에 쓰시는 분들 좀 안계신가요? 어디 자료를 찾아봐도 제대로 있질 않아서... 다른 분들은 어떠신지 궁금합니다.

그럼, 이만...

indizarm의 이미지

bugiii님 답변 '또' 감사합니다.

Quote:
select 는 잘 쓰면 참 좋긴한데 (자신만의 뭔가가 있다면... 하지만 이걸로 어느정도 규모가 되어버리면 저같이 머리 나쁜 사람은... 좌절...)...

괜히 뜨끔하군요. -_-?;; 개념이 오락 가락하는 상태라서... 윽

'개미 글씨'도 재미있습니다.

좋은 하루되세요 ^_^

//______________________이하 수정된 후 덧붙임

결국은 clnt에서도 select()로 처리했지만
왠지 모르게 어색하군요.... -_-;;

What a Cool Days!!!

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.