소켓프로그래밍에서 쓰레드에 대해 궁금한점 올립니다

ch0nn0m의 이미지

윤성우 저자의 소켓프로그래밍인데요...
쓰레드부분인데 이해가 안가는 부분을 주석처리 해놨습니다...부탁드릴게요..^^;

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <arpa/inet.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <pthread.h> 
 
#define BUFSIZE 100 
 
void * clnt_connection(void *arg); 
void send_message(char * message, int len); 
void error_handling(char *message); 
 
int clnt_number=0; 
int clnt_socks[10]; 
pthread_mutex_t mutx; 
 
int main(int argc, char **argv) 
{ 
  int serv_sock; 
 
  int clnt_sock; 
  struct sockaddr_in serv_addr; 
  struct sockaddr_in clnt_addr; 
  int clnt_addr_size; 
  pthread_t thread; 
 
  if(argc!=2) { 
    printf("Usage : %s <port>\n", argv[0]); 
    exit(1); 
  } 
 
  if(pthread_mutex_init(&mutx, NULL)) 
    error_handling("mutex init error"); 
 
  serv_sock=socket(PF_INET, SOCK_STREAM, 0); 
 
  memset(&serv_addr, 0, sizeof(serv_addr)); 
  serv_addr.sin_family=AF_INET; 
  serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); 
  serv_addr.sin_port=htons(atoi(argv[1])); 
 
  if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1) 
    error_handling("bind() error"); 
 
  if(listen(serv_sock, 5)==-1) 
    error_handling("listen() error"); 
 
  while(1){ 
    clnt_addr_size=sizeof(clnt_addr); 
 
    clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr,&clnt_addr_size); 
 
    pthread_mutex_lock(&mutx); 
 
    <span>// accept함수는 클라이언트가 접속할때마다 accept를 하여 파일디스크립터를 계속 생성하는 건가요??</span>    clnt_socks[clnt_number++]=clnt_sock; 
    pthread_mutex_unlock(&mutx); 
 
    pthread_create(&thread, NULL, clnt_connection, (void*)clnt_sock);  
    printf("새로운 연결, 클라이언트 IP : %s \n", inet_ntoa(clnt_addr.sin_addr)); 
  } 
 
  return 0; 
} 
 
void * clnt_connection(void *arg) 
{ 
  int clnt_sock= (int)arg; 
  int str_len=0; 
  char message[BUFSIZE]; 
  int i; 
 
  while( (str_len=read(clnt_sock, message, sizeof(message))) != 0) 
    send_message(message, str_len); 
 
  pthread_mutex_lock(&mutx);
 
 <span>//여기 밑에부분 clnt_number는 여기 clnt_connection함수안에는 없는 변수입니다...전역변수로 선언된 clnt_number인 0이 들어가야되는게 아닌가요?? 그렇다면 결과가 이상하지 않나요?? </span>
  for(i=0; i<clnt_number; i++){  
 
    if(clnt_sock == clnt_socks[i]){ 
      for( ; i<clnt_number-1; i++) 
          clnt_socks[i]=clnt_socks[i+1]; 
      break; 
    } 
  } 
  clnt_number--; 
  pthread_mutex_unlock(&mutx); 
 
  close(clnt_sock); 
  return 0; 
} 
 
void send_message(char * message, int len) 
{ 
  int i; 
 
  pthread_mutex_lock(&mutx); 
  for(i=0; i<clnt_number; i++) 
    write(clnt_socks[i], message, len); 
  pthread_mutex_unlock(&mutx); 
} 
 
void error_handling(char *message) 
{ 
  fputs(message, stderr); 
  fputc('\n', stderr); 
  exit(1); 
} 

2가지가 궁금합니다...위에 표시한대로...
accpet는 새로운 클라이언트가 접속할때마다 파일디스크립터가 생성되는건지...?

함수안에 없는 clnt_number를 불러오는데...전역변수인 0을 읽어오는게 아닌건지..??
0을 읽어오면 이상해지는거 아닌지요??

charsyam의 이미지

스레드가 생성되는 시점에 전역변수의 값이 이미 증가되었습니다.

동기화도 뮤텍스로 하고 있구요.

천천히 살펴보시면 정상적으로 동작하는 코드입니다.

clnt_socks[clnt_number++]=

=========================
CharSyam ^^ --- 고운 하루
=========================

=========================
CharSyam ^^ --- 고운 하루
=========================

mach의 이미지

accept()는 운영체제가 제공하는 시스템호출입니다.

질문하신바대로 accept()는 매번 정상 리턴시(신규 클라이언트 접속시) 소켓을 하나 생성하여 그 소켓디스크립터를 리턴하게 되어 있습니다.

달리 말하자면, 소켓 디스크립터(파일 디스크립터)를 매 정상 리턴시마다 신규 생성합니다.

* 당연히, 비정상시(에러 또는 시그널발생시) -1을 리턴하므로 리턴값에 유의하여 프로그래밍이 필요합니다.
* 부가적으로, read(), write()도 마찬가지로 리턴값에 유의하셔야 합니다.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

댓글 달기

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