블로그 이미지
송시혁

calendar

1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

Notice

Tag

Recent Post

Recent Comment

Recent Trackback

Archive

2013. 7. 9. 14:46 네트워크/vmware 실습


다음예제는 TCPserver소스


#include "smart.h"
#include <pthread.h>

#define MAXPENDING   5
#define MAXUSER    10
void *ClientRecv(void *);

////// Critical Section  Start////
unsigned int    uiUser;
pthread_t       tID[MAXUSER];
///////// 크리티컬 섹션 End//////
pthread_mutex_t    MLock;

int main(int iArg, char *cpArg[])
{
  int servSock; 
  int clntSock[MAXUSER];
  int tempSock;
  struct sockaddr_in echoServAddr;
  struct sockaddr_in echoClntAddr;
  unsigned short echoServPort;
  unsigned int clntLen;
  int iRet;
  int iCnt;
  int iCnt2;
  unsigned char ucBuff[500];
  
  if(iArg)
  {
    echoServPort=9998;
  }    
  else if(2==iArg)
  {
    echoServPort=atoi(cpArg[1]);
  }
  servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if(0 > servSock)
  {
    printf("socket() failed");

    return 0;
  }




  memset(&echoServAddr, 0sizeof(echoServAddr));
  echoServAddr.sin_family = AF_INET;
  echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  echoServAddr.sin_port = htons(echoServPort);

  iRet = bind(servSock, (struct sockaddr *)&echoServAddr, sizeof(echoServAddr));
  if(0 > iRet)
  {
    close(servSock);
    printf("bind() failed");
  
    return 0;
  }

  iRet = listen(servSock, MAXPENDING);
  if(0 > iRet)
  {
    close(servSock);
    printf("listen() failed");

    return 0;
  }

  clntLen = sizeof(echoClntAddr);

  uiUser = 0;
  while(1)
  {
    tempSock = accept(servSock, (struct sockaddr *)&echoClntAddr, &clntLen);
    if(0 > tempSock)
    {
      printf("accept() failed");
      continue;  
    }  
    printf("Handling client ip : %s\n", inet_ntoa(echoClntAddr.sin_addr));
    printf("Handling client port : %d\n", ntohs(echoClntAddr.sin_port));
    printf("Handling client socket number : %d\n", tempSock);
    if(MAXUSER <= uiUser)
    {
      close(tempSock);
      continue;
    }
    
    pthread_mutex_lock(&MLock);//mutex 동기화 매카니즘 함수중의 하나.
    pthread_create(&tID[uiUser],0, ClientRecv, &tempSock); //uiUser는 접속자수, 세번째 인자는 ClientRecv함수를 호출.
    ++uiUser;
    pthread_mutex_unlock(&MLock);

    
    while(0!=tempSock);// 여기서 지연시키지 않으면, 쓰레드를 생성해서 쓰레드가 가지고 있는 데이터가 잘못될 수 있기 때문.
                           //
    printf("현재 접속자 수 : %d\n", uiUser);//
  }
  
  close(servSock);  
  
  return 0;
}

void *ClientRecv(void *vp)
{
  int iSock = *((int *)vp);// ClientRecv가 클라이언트의 데이터를 인자로 받고 변수 iSock에 집어넣는다.
  unsigned char ucBuff[500];
  int iRet;
  
  *((int*)vp)= 0;//
  
  while(1)
  {
    iRet = read(iSock, ucBuff, 500);//iSock에 있는 데이터를 읽어들인다. (클라이언트 정보 읽는다.)
    if(1>iRet)
    {
      break;
    }
    
    ucBuff[iRet-1]=0;//엔터제거
    printf("[%dsock]:[%s]\n", iSock, ucBuff);//번호와 문자열(수신된 데이터)
    if('$'==ucBuff[0])
    {
      break;
    }
  }
  --uiUser;//유저수를 감소시킨다.
  close(iSock);
  return 0;
  
}










세밀하게 수정 된 부분.


#include "smart.h"
#include <pthread.h>
#define MAXPENDING   5
#define MAXUSER    10

typedef struct _Tinfo
{
  unsigned int   uiUser;
  int        iSock;
}Tinfo;

void *ClientRecv(void *);

////// Critical Section  Start////
unsigned int    uiUser;
pthread_t       tID[MAXUSER];
///////// 크리티컬 섹션 End//////
pthread_mutex_t    MLock;

int main(int iArg, char *cpArg[])
{
  int servSock; 
  Tinfo stTempinfo;
  struct sockaddr_in echoServAddr;
  struct sockaddr_in echoClntAddr;
  unsigned short echoServPort;
  unsigned int clntLen;
  int iRet;
  int iCnt;
  int iCnt2;
  unsigned char ucBuff[500];
  
  if(iArg)
  {
    echoServPort=9998;
  }    
  else if(2==iArg)
  {
    echoServPort=atoi(cpArg[1]);
  }
  servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if(0 > servSock)
  {
    printf("socket() failed");

    return 0;
  }

  memset(&echoServAddr, 0sizeof(echoServAddr));
  echoServAddr.sin_family = AF_INET;
  echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  echoServAddr.sin_port = htons(echoServPort);

  iRet = bind(servSock, (struct sockaddr *)&echoServAddr, sizeof(echoServAddr));
  if(0 > iRet)
  {
    close(servSock);
    printf("bind() failed");
  
    return 0;
  }

  iRet = listen(servSock, MAXPENDING);
  if(0 > iRet)
  {
    close(servSock);
    printf("listen() failed");

    return 0;
  }

  clntLen = sizeof(echoClntAddr);

  uiUser = 0;
  pthread_mutex_init(&MLock, NULL);//NULL로 초기화하는 함수.
  while(1)
  {
    stTempinfo.iSock = accept(servSock, (struct sockaddr *)&echoClntAddr, &clntLen);
    if(0 > stTempinfo.iSock)
    {
      printf("accept() failed");
      continue;  
    }  
    printf("Handling client ip : %s\n", inet_ntoa(echoClntAddr.sin_addr));
    printf("Handling client port : %d\n", ntohs(echoClntAddr.sin_port));
    printf("Handling client socket number : %d\n", stTempinfo.iSock);
    if(MAXUSER <= uiUser)
    {
      close(stTempinfo.iSock);
      continue;
    }
    
    pthread_mutex_lock(&MLock);
    stTempinfo.uiUser=uiUser;
    pthread_create(&tID[uiUser],0, ClientRecv, &stTempinfo);//
    ++uiUser;
    pthread_mutex_unlock(&MLock);//

    while(0!=stTempinfo.iSock);// 
    printf("현재 접속자 수 : %d\n", uiUser);
  }
  
  close(servSock);  
  
  return 0;
}

void *ClientRecv(void *vp)
{
  unsigned char ucBuff[500];
  int iRet;
  int iSock = ((Tinfo *)vp)->iSock;
  unsigned int uiMyUser=((Tinfo *)vp)->uiUser;
  
  ((Tinfo*)vp)->iSock= 0;
  
  while(1)
  {
    iRet = read(iSock, ucBuff, 500);
    if(1>iRet)
    {
      break;
    }
    
    ucBuff[iRet-1]=0;
    printf("[%dsock]:[%s]\n", iSock, ucBuff);
    if('$'==ucBuff[0])
    {
      break;
    }
  }
  pthread_mutex_lock(&MLock);
  --uiUser;
  tID[uiMyUser]=tID[uiUser];
  pthread_mutex_lock(&MLock);
  close(iSock);
  return 0;
  
}



posted by 송시혁