소켓프로그래밍 accpet함수 마지막인자(3번째인자)의 주소값으로 넘겨주는 이유가 궁금합니다.

gohy의 이미지

accpet(int serv_sock,struct sockaddr* addr, socklen_t* addrlen) 함수의 형태에서 3번째(마지막 인자)로 addrlen의 주소값을 넘겨주는 이유가 궁금합니다.

(현재 윤성우님의 TCP/IP 프로토콜을 보며 공부중입니다.)
보통 예제에서는
---------------------------------------------------------------------------
clnt_addr_size = sizeof(clnt_addr)
clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size)
---------------------------------------------------------------------------

이런식으로 서버측에서 accept함수를 호출하던데 clnt_addr_size가 어차피 accept()함수 내부에서 갱신되기에 주소값을 넘겨주는 형태인것 같은데 그 이전에
clnt_addr_size = sizeof(clnt_addr) 문장이 필요한지 ;;;;

빠른답변 부탁드립니다ㅜ

joyyir의 이미지

알파고JA ㅎㅇ

yhsuk의 이미지

구글링 해서도 알 수 있겠지만, 정확한 함수 사용법에 대해서는 매뉴얼을 같이 확인해 보시는 것이 좋습니다;;
제가 확인하는 man 페이지에는 다음과 같이 나옵니다.

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

The argument addr is a pointer to a sockaddr structure.  This structure is filled in with the address of the peer socket, as known to the communications layer.  
The exact format of the address returned addr is determined by the socket’s address family (see socket(2) and the respective protocol man pages).  
When addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL.
 
The addrlen argument is a value-result argument: the caller must initialize it to contain the size (in bytes) of the structure pointed to by addr; 
on return it will contain the actual size of the peer address.
 
The returned address is truncated if the buffer provided is too small; 
in this case, addrlen will return a value greater than was supplied to the call.

대충, 해석해 보면
client peer의 address가 필요없으면 addr을 NULL로 주고, addrlen은 사용되지 않습니다.
addrlen은 입/출력에 사용되는 인자로 사용자는 반드시 addr을 addr이 가리키는 구조체의 크기를 할당하고 호출되어야 합니다; 리턴시에는 client peer address의 실제 크기를 가집니다.

제공되는 버퍼크기가 너무 작으면, 반환되는 address는 잘립니다; 이 경우엔, addrlen은 호출시 제공된 값보다 더 큰 값이 리턴됩니다.
---
결론적으로는, 제공 버퍼 크기가 작아서 프로그램이 죽는 경우(Seg-fault)를 방지하기 위해서입니다.

Signature :) - "여유를 갖고 행동하되 게을러지지 말자"

익명 사용자의 이미지

답글 달아주셔서 정말 감사합니다!!

구글링의 필요성 다시한번 꺠닫게 되네요~

한가지 의문이 남아있는 것은 제공 버퍼의 크기가 작아서 프로그램이 죽는경우를 방지함이라고 말씀해주셨는데,

무슨 버퍼가 작아서 죽을수도 있는 건지 이해가 잘 되지않습니다.

accept()함수 내부에 존재하는 버퍼가 죽는다는 말씀이신지.... 저로서는 많이 부족한 것들이 많아서 이해가 잘 되지 않습니다ㅜ

yhsuk의 이미지

음.. 그냥 일반적인 내용인데,
accept함수가 addr 버퍼의 크기를 입력 데이터로 받지 않는다고 가정해 보면,
accept함수는 addr 버퍼의 크기를 알 수가 없으므로, 보통은 사용자가 충분한 버퍼를 제공했다고 생각하고 쓸 데이터를 다 쓰도록 구현되겠지요?

그런데 실제로는, addr 버퍼의 크기보다 accept함수가 쓸 데이터가 크면, 버퍼의 경계를 넘어 데이터를 기록하게 되고, 이것을 버퍼 오버플로우라고 합니다.

버퍼 오버플로우가 나면 죽는다고 썼는데, 항상 그런건 아니고 아래 링크처럼 여러가지 (안 좋은) 결과들로 나타날 수 있습니다.

https://ko.wikipedia.org/wiki/%EB%B2%84%ED%8D%BC_%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C

개인이 함수를 만들 때에도 버퍼 같은 게 인자로 있으면, 항상 그 버퍼의 size도 같이 인자로 넘기도록 디자인하는 게 좋습니다.
버퍼 오버플로우를 막기 위해 사용되는 함수들에 대한 내용: https://kldp.org/node/69784

Signature :) - "여유를 갖고 행동하되 게을러지지 말자"

bushi의 이미지

Comparison of Socket Address Structures
Structure 가 아니라 Structures 라는 점에 유의하시고...

+
달고 보니 엉뚱한 댓글이네요. 왜 포인터로 넘겼냐는 질문에 대한 답은 이미 달렸는데...

익명 사용자의 이미지

답글들 꼼꼼히 읽어보도록 하겠습니다!!!

익명 사용자의 이미지

답글들 꼼꼼히 읽어보도록 하겠습니다!!!

댓글 달기

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