<NETWORK>



=입출력 다중화

-인터럽트 + 폴링



=SELECT()


-fd_set : 128 byte = 1024 bit


장치들의 상태 모니터링 가능 (0,1,2-stdin,stdout,stderr ...)



int select( ,R,W,E, );











select() blocking => R, W, E 중 이벤트 감지가 되면 BLOCKING 풀림


-timeout 0 => 무한 대기


-select()인자 : (감시대상 번호(ex : 2) + 1, READ, WRITE, ERROR, TIMEOUT)



=>멀티 스레드/ 멀티 프로세스 사용 없이 채팅 가능


=select() + 채팅 프로그램 : 멀티 프로세스 대신 사용


<smartsock2.h>

#ifndef __SMARTSOCK2_H__
#define __SMARTSOCK2_H__

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/select.h>

#define PORT    7777
#define IP      "192.168.0.219"

#define MSG_SIZE    255
#define BUF_SIZE    (MSG_SIZE + 1)
#define MSG_END     "quit"
#define MAX_USER  30
#endif //__SMARTSOCK2_H__


<client2.c>

#include "smartsock2.h"

int main(int argc, char **argv)
{
  
int iFd;
  
struct sockaddr_in stAddr;
  
int iLen;
  
int iRet;
  fd_set fdRead;
  
char cBuffer[BUF_SIZE];

  iFd 
= socket(AF_INET, SOCK_STREAM, 0);
  
if(-1 == iFd)
  {
    perror(
"socket() call error :");
    
return 100;
  }

  stAddr.sin_family 
= AF_INET;
  stAddr.sin_addr.s_addr 
= inet_addr(IP);
  stAddr.sin_port 
= htons(PORT);

  iLen 
= sizeof(struct sockaddr_in);

  iRet 
= connect(iFd, (struct sockaddr*)&stAddr, iLen);
  
if(-1 == iRet)
  {
    perror(
"connect() call error :");
    close(iFd);
    
return 200;
  }

  
while(1)
  {
    FD_ZERO(
&fdRead);
    FD_SET(
0&fdRead);
    FD_SET(iFd, 
&fdRead);
    select(iFd+
1&fdRead, 000);
    
if(0 != FD_ISSET(0&fdRead))
    {
      iRet 
= read(0, cBuffer, MSG_SIZE);
      cBuffer[iRet - 
1= 0;
      write(iFd, cBuffer, MSG_SIZE);
      printf(
"[Send MSG] : [%s]\n", cBuffer);
    }
    
if(0 != FD_ISSET(iFd, &fdRead))
    {
      read(iFd, cBuffer, MSG_SIZE);
//iFd:네트워크
      printf("[Server MSG] : [%s] \n", cBuffer);
    }
    
if(0 == strncmp(cBuffer, MSG_END, strlen(MSG_END)))
    {
      
break
;
    }

  }

  close(iFd);

  
return 0;
}


<server2.c>

#include "smartsock2.h"

int main(void)
{
  
int iSock; //socket 생성
  struct sockaddr_in stAddr; //socket의 주소
  int iRet; //error 값은 저장한다.
  int iCSock[MAX_USER]; //새로운 소켓을 저장할 변수이다.
  unsigned int uiUser;
  socklen_t uiSockLen 
= sizeof(struct sockaddr); //unsigned int이다.
  char cBuffer[BUF_SIZE]; //echo서버를 위한 변수
  iSock = socket(AF_INET, SOCK_STREAM, 0); //socket 생성
  fd_set fdRead;
  
unsigned int uiCnt;

  
if(iSock < 0//socket 에러 확인
  {
    perror(
"socket() error : ");
    close(iSock); 
//리턴하기 전에 close도 해주어야한다.
    return 10;
  }

  bzero(
&stAddr, sizeof(stAddr)); //구조체를 지운다.
  stAddr.sin_family = AF_INET;    //
  stAddr.sin_port = htons(PORT);          //고정 PORT
  stAddr.sin_addr.s_addr = inet_addr(IP); //고정 IP

  iRet = bind(iSock, (struct sockaddr *)&stAddr, sizeof(stAddr));
  
if(iRet < 0//bind 에러 확인
  {
    perror(
"bind() error : ");
    close(iSock); 
//리턴하기 전에 close도 해주어야한다.
    return 15;
  }

  iRet 
= listen(iSock, 5);
  
if(iRet < 0)
  {
    perror(
"listen() error : ");
    close(iSock); 
//리턴하기 전에 close도 해주어야한다.
    return 20;
  }
  uiUser 
= 0;
  
while(1)
  {
    FD_ZERO(
&fdRead);
    FD_SET(
0&fdRead);
    FD_SET(iSock, 
&fdRead);
    
for(uiCnt = 0; uiCnt < uiUser ;++uiCnt)
    {
      FD_SET(iCSock[uiUser], 
&fdRead,0,0,0);
    }
    select(iSock+
1&fdRead, 000);
    
if(0 != FD_ISSET(iSock, &
fdRead))
    {
      iCSock[uiUser] 
= accept(iSock, (struct sockaddr*)&stAddr, &uiSockLen);
      
if(iCSock[uiUser] < 0)
      {
        perror(
"accept() error : ");
        
continue;
      }
      ++uiUser;
    }
  }

  close(iSock);  
//
  printf("incoming client\n"); //누군가 접근중이다.

  printf("client IP : [%s]\n", inet_ntoa(stAddr.sin_addr)); //client IP
  printf("client PORT : [%d]\n", ntohs(stAddr.sin_port)); //client PORT

  write(iCSock, "Welcome!"sizeof("Welcome!"));

  
while(1)
  {
    read(iCSock, cBuffer, MSG_SIZE); 
//
    printf("[Client]: [%s]\n", cBuffer);
    write(iCSock, cBuffer, MSG_SIZE);
    
if(0 == strncmp(MSG_END, cBuffer, strlen(MSG_END))) //
    {
      
break;
    }
  }

  close(iCSock);

  
return 0;
}











=정리필요

uiUser

iCSock




'2015 스마트 콘트롤러 > 업무일지' 카테고리의 다른 글

20150826  (0) 2015.08.26
20150825  (0) 2015.08.25
20150821  (0) 2015.08.23
20150820  (0) 2015.08.21
20150819  (0) 2015.08.19
Posted by ahj333
,