소켓 - 서버에서 클라이언트 주소 구분하기

kakalot81의 이미지

소켓 통신에서 서버 : S // 클라이언트 : C1, C2 가 있다고 가정합니다.

S에서 C1, C2의 구조체정보를 가져올때 accept함수를 써서 등록한다고 알고 있습니다.
그런데 S, C1, C2가 백그라운드 실행이 아닌 동시에 실행되는 프로그램에서(ex-mpich(병렬))
연산이 빠른 C2가 항상 먼저 S의 accept에 접근해서, C1을 S에 먼저 쓰려는 의도와 어긋나버립니다.
(C2에 sleep을 약간 주고 실행하면 원하는 순서로 잡히긴 하지만 이는 근본적인 해결책이 아니죠.)

S에서 C1, C2의 ip주소를 구분해 accept하는 방법이 분명 있을텐데 몇일째 헤메고 있네요. 아래는 간추린 참고코드입니다.

Server - (192.168.0.1)

...
fd1 = accept(sockfd, (struct sockaddr *)&C1_addr, &sin_size);
fd2 = accept(sockfd, (struct sockaddr *)&C2_addr, &sin_size);
printf("server : got connection from Client1 %s\n", inet_ntoa(C1_addr.sin_addr));
printf("server : got connection from Client2 %s\n", inet_ntoa(C2_addr.sin_addr));
...

Client-(192.168.0.2, 192.168.0.3)

/*각 클라이언트가 동시에 실행*/... 
connect(sockfdc, (struct sockaddr *)&Server_addr, sizeof(struct sockaddr);
...

결과

server : got connection from Client1 192.168.0.3
server : got connection from Client2 192.168.0.2

출력값인 클라이언트의 ip주소가 클라이언트를 동시에 실행하니 뒤죽박죽 순서로 잡히는데 원하는대로 제어하려면 구체적으로 어떤 방법이 있을까요?
Server에서 Client_addr의 구조체정보를 accept 이전에 미리 선언해 봐도 아무 소용 없더라구요.ㅜㅡ

pizza1977의 이미지

서버 소켓에서 Connect하는 클라이언트를 필터링 할 수 있는 상황은
어떻게든 Accept가 이루어져 클라이언트 소켓이 반환되는 시점부터 입니다.
Accept가 이루어 지면 Client에서는 Connect가 정상 반환 되구요.

이건 소켓 알고리즘 상에서 할 수 있는 일 이라기 보다는 그 윗단의
통신 시나리오(응용 레벨의 프로토콜)를 통해 해결해야 할 것 같네요.

즉, 접속 요청한 클라이언트 정보를 확인하여 순서가 안맞을 경우
해당 세션을 끊어 버리는 거죠. 그럼 클라이언트에서는 계속 반복적으로
접속을 시도하고...

제가 알고 있는 건 이부분 까지인데... 이게 원하는 답은 아닌듯 싶어서...

다른 분들 답을 기다려 봐야겠네요.

-------------
포탈이는 불사신

-------------
포탈이는 불사신

ymir의 이미지

지난번 쓰레드하고 계속 이어지는 내용이로군요.
뭔가 계속 노력을 하시는 모습은 좋아보입니다..

서버나 클라이언트 프로그램에 하드코딩 하지 않는 한, 위 환경에서는 어려울 겁니다.
(보아하니, 간단한 C/S 프로그램을 응용해서 작성하신 것 같네요..)

지난번에 프로토콜 말씀드렸었는데.. ;;
TCP/IP 가 각각의 계층에서 데이터 전송을 위해 미리 정해진 프로토콜이듯이..
어플리케이션에서도 임의의 프로토콜을 정의할 수 있습니다.
tcp/ip 를 흉내내어 구조체로 정의해도 좋고, 문자열로 정의해도 좋습니다.
(이를테면 ftp 나 telnet 이 각각의 서비스를 위해 정의된 프로토콜입니다.)

위와 같은 경우라면, 소켓에 연결된 후에, 각각의 클라이언트가 미리 약속된 데이터를 보내면,
서버에서는 해당 데이터를 읽어들여, 처리를 하도록 하면 될 것 같네요.

간단한 예로, client 는 입력값으로 server address 및 priority 를 받아, 해당 server 에 connect 를 한다. connect 가 성공하면, (미리 약속된) "REGISTER:CLIENT1:PRIORITY=1\r\n" 문자열을 보내고, 서버에서 응답 ("OK\r\n" or "FAIL\r\n") 이 오기를 기다린다. "OK" 라는 문자열이 도착하면, 정상적으로 신호를 받을 준비가 된 것이므로, 신호 처리 루틴으로 이동한다.

server 는, 작업용 thread 를 생성하여, client list 에 등록된 client ip 에 정보를 전송하도록 한다. accept 용 thread 에서는 accept() 에서 연결 요청이 들어오면, 해당 socket 으로부터, "REGISTER:CLIENT1:PRIORITY=1\r\n" 와 같은 문자열이 도착하길 기다린다. 정해진 시간내에 해당 문자열이 도착하지 않으면, 비정상 접속으로 간주하고, 접속을 종료한다. 문자열을 파싱하여 client 정보를 list 에 추가한다. 이때 priority 가 높은 녀석순으로 sort 되도록 한다. (이 client list 는 작업용 list 에서 사용한다.)

간단하게 명세서를 적어봤는데, 이런식으로 응용프로그램에서 사용할 프로토콜 및 동작을 정의하고, 그 규약에 맞게 동작하도록 코딩하면 됩니다.
(위 내용에서라면, 단순히는 select 만 써서 할 수도 있겠지만, 추가적으로 쓰레드 동기화나 프로세스간 통신 등을 공부해야 합니다.)

하드코딩 할거라면, client 정보를 저장할 구조체를 두 개 (primary, secondary) 정의하고, client 의 ip 를 비교해서 각각의 구조체에 저장해 주면 될 것 같은데요.. (굳이 연결 순서에 의존할 필요는 없을 듯...)

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

댓글 달기

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