블로그 이미지
초딩입맛제주아재
하고 싶은 것만 하며 살고 싶다

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 31  
2006. 10. 13. 11:19 Programing/PHP

server.php

set_time_limit(0);

define("_IP",    {IP});
define("_PORT",  {PORT});
define("_TIMEOUT", 10);

$cSock = array();
$cInfo = array();

$sSock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_bind($sSock, _IP, _PORT);
socket_listen($sSock);

while(1)
{
  $sockArr = array_merge(array($sSock), $cSock);

  if(socket_select($sockArr, $tWrite = NULL, $tExcept = NULL, _TIMEOUT) > 0)
  {
       foreach($sockArr as $key => $sock)
       {
           // Listen 하고 있는 서버 소켓일 경우
           // 새로운 클라이언트의 접속을 의미
           echo $sock.'/'.$sSock."\n";

           if($sock == $sSock)
           {
               $tSock = socket_accept($sSock);

               socket_getpeername($tSock, $sockIp, $sockPort);

               $cSock[$tSock] = $tSock;
               $cInfo[$tSock] = array('ip'=>$sockIp, 'port'=>$sockPort);

               msg("client connect : ".$sockIp.":".$sockPort."\n");
           }
           // 클라이언트 접속해 있는 소켓중 하나일경우
           // 해당 클라이언트에서 이벤트가 발생함을 의미
           else
           {
               $buf = socket_read($sock, 4096);

               // 접속 종료
               if(!$buf)
               {
                   exceptSocket($cSock, $cInfo, $sock);
                   msg("client connection broken : ".$sockIp.":".$sockPort."\n");
               }
               // 메시지 수신 이벤트
               else
               {
                   msg("recive data : ".$buf."\n");

                   $thisSockInfo = $cInfo[$sock];
                   //$cmd = substr($buf, 0, 4);
                   $cmd = $buf;

                   switch($cmd)
                   {
                       // 시간전송
                       case "time":
                           msg("client(".$thisSockInfo['port'].") time data request\n");
                           socket_write($sock, date("Y/m/d H:i:s"));
                           break;

                       // 종료
                       case "quit":
                           msg("client(".$thisSockInfo['port'].") quit request\n");
                           socket_write($sock, "quit");
                           socket_close($sock);
                           exceptSocket($cSock, $cInfo, $sock);
                           break;
                       default:
                           if(substr($cmd,0,1) == ':'){
                               msg("client(".$thisSockInfo['port'].") sendmsg : ".substr($cmd,1)."\n");
                               broadCasting($sockArr,$sock,substr($cmd,1));
                           }else{
                               msg("client(".$thisSockInfo['port'].") invalid command $cmd\n");
                           }
                           break;
                   }
               }
           }
       }
  }

  $i++;

}

function exceptSocket(&$sockSet, &$infoSet, $sock)
{
  unset($sockSet[$sock]);
  unset($infoSet[$sock]);
  // array_merge 함수에서 error 발생을 막기위한 처리
  if(count($sockSet)==0)
  {
       $sockSet = array();
       $infoSet = array();
  }
}

function msg($msg)
{
  echo "SERVER >> ".$msg;
}

function broadCasting($socks,$cSock,$msg){
  global $sSock;

  foreach($socks as $key => $sock){
       if($sock != $sSock && $sock != $cSock){
           socket_write($sock,$msg);
       }
  }
}

client.php

define("_IP",    {IP});
define("_PORT",  {PORT});

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_connect($sock, _IP, _PORT);

msg("socket connect to "._IP.":"._PORT."\n");

while(1)
{
  msg("Enter command time or quit : ");

  // 사용자의 명령어를 입력받습니다.
  $stdin = ereg_replace("\n|\r", "", read_data());
  //$stdin = substr($stdin, 0, 4);

  // time 또는 quit 메시지 말고는 무시 합니다.
  if($stdin == "time" || $stdin == "quit")
  {
       msg("Input command : ".$stdin."\n");
  }else{
       if(substr($stdin,0,1) == ':'){
           msg("sendmsg : ".$stdin."\n");
       }else{
           msg("invalid command (not send). If you want said ':' and your message.: ".$stdin."\n");
           continue;
       }
  }

  socket_write($sock, $stdin);
  $sMsg  = socket_read($sock, 4096);

  if(substr($sMsg, 0, 4) == 'quit')
  {
       socket_close($sock);
       exit;
  }else
  {
       msg("recived data : ".$sMsg."\n");
  }
}

// 표준입력을 받아 값을 리턴하는 함수
function read_data()
{
  $in = fopen("php://stdin", "r");
  $in_string = fgets($in, 255);
  fclose($in);
  return $in_string;
}

// 로그 출력
function msg($msg)
{
  echo "CLIENT >> ".$msg;
}

단방향 채팅프로그램이다...-_-;
서버에 지정된 명령어에 의해 클라이언트의 메세지를 처리해주는 정도...
다중 클라이언트 접속이 허용되지만
클라이언트간 메세지 교환은 이루어지지 않고
클라이언트 대 서버의 통신만 가능하다.
서버에서 클라이언트의 메세지를 전체 클라이언트에게 뿌려주는
브로드캐스팅 구현이 안됐다...



TODO:
1.서버의 브로드캐스팅을 구현해야 실질적인 다중채팅이 이루어진다.
2.서버에서 임의의 메세지를 전송 하는 기능을 구현해야 한다.

'Programing > PHP' 카테고리의 다른 글

[OSX] Eclipse에서 PHP 로컬 개발/테스트 환경 구축하기  (4) 2008.08.30
Enabling PHP and Apache in Leopard  (2) 2008.08.19
WAV파일 분석  (0) 2006.11.10
간단한 소켓통신  (0) 2006.10.13
간단한 대화식 프로그램  (0) 2006.07.24
시스템 모니터링 툴  (0) 2006.07.17
posted by 초딩입맛제주아재
TAG ,

댓글을 달아 주세요

prev 1 2 3 4 5 6 next