2013-04-30 2 views
4

저는 소켓 연결을위한 초보자입니다. 소켓 서버에 몇 가지 명령을 보내고 싶지만 다른 메시지가 아닌 첫 번째 메시지 만 보낼 수 있습니다.소켓 클라이언트가 메시지를 보내십시오.

클라이언트 :

처음 $cmd_1 같은 여러 메시지를 보내고, 내가 $cmd_2을 보낼 수있는 결과에 따라 어떻게
$fp = stream_socket_client("tcp://127.0.0.1:1000", $errno, $errstr, 30); 
if (!$fp) { 
    echo "$errstr ($errno)<br />\n"; 
} else { 
    $cmd_1 = "hello"; 
    fwrite($fp, $cmd_1); 
    while (!feof($fp)) { 
     print_r(fgets($fp, 1024)); 
    } 
    $cmd_2 = "second message"; 
    fwrite($fp, $cmd_2); 
    while (!feof($fp)) { 
     print_r(fgets($fp, 1024)); 
    } 
    fclose($fp); 
} 

?

서버

error_reporting(E_ALL); 

/* Allow the script to hang around waiting for connections. */ 
set_time_limit(0); 

/* Turn on implicit output flushing so we see what we're getting 
* as it comes in. */ 
ob_implicit_flush(); 

$address = '127.0.0.1'; 
$port = 1000; 

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { 
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; 
} 

if (socket_bind($sock, $address, $port) === false) { 
    echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; 
} 

if (socket_listen($sock, 5) === false) { 
    echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; 
} 

do { 
    if (($msgsock = socket_accept($sock)) === false) { 
     echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; 
     break; 
    } 
    /* Send instructions. */ 
    $msg = "\nWelcome to the PHP Test Server. \n" . 
     "To quit, type 'quit'. To shut down the server type 'shutdown'.\n"; 
    socket_write($msgsock, $msg, strlen($msg)); 

    do { 
     if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) { 
      echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"; 
      break 2; 
     } 
     if (!$buf = trim($buf)) { 
      continue; 
     } 
     if ($buf == 'quit') { 
      break; 
     } 
     if ($buf == 'shutdown') { 
      socket_close($msgsock); 
      break 2; 
     } 
     $talkback = "PHP: You said '$buf'.\n"; 
     socket_write($msgsock, $talkback, strlen($talkback)); 
     echo "$buf\n"; 
    } while (true); 
    socket_close($msgsock); 
} while (true); 

socket_close($sock); 
+0

당신의 오류가 무엇입니까? 사실 귀하의 질문은 무엇입니까? – leftclickben

+0

나는 단지 첫 번째 메시지를 보낼 수있다. 나는 두 번째가 아니라 첫 번째 메시지에 대한 응답을 얻는다. – user2136174

+0

서버의 동작에 대한 확신이 있습니까? 고객으로부터받은 각 입력에 응답해야합니까? fgets 및 fwrite 함수의 반환 값을 확인해야합니다. – Marcassin

답변

0

문제는 아래 라인에 있습니다

while (!feof($fp)) { 

가 무슨가하는 것은 : 그것은 그 소켓의 EOF (일반적으로 가까운 소켓)을 기다립니다. 그것은 첫 번째 응답을 얻고 더 이상의 요청을 보내지 않고 추가 응답을 기다립니다 (while 루프). 보내는 모든 요청 메시지에 대한 응답 메시지를 읽는 것이 좋습니다.

은 다음과 같이 코드를 수정 (테스트되지 않은,하지만 작동합니다) :

$cmd_1 = "hello"; 
fwrite($fp, $cmd_1); 
print_r(fgets($fp, 1024)); 

$cmd_2 = "second message"; 
fwrite($fp, $cmd_2); 
print_r(fgets($fp, 1024)); 

fclose($fp); 

fgets(..)는 소켓에서 한 번 라인을 읽을 때 반환합니다. 실제로 while 루프가 필요하지 않습니다.


또한 좋은 점은 통신을위한 구조/프로토콜을 정의하기 시작하는 것입니다. 클라이언트 쪽에서는 줄 단위로 읽지 만 서버는 읽지 않습니다. 소켓 (서버)은 을 읽을 수 있습니다. 부분 메시지가 표시됩니다. 통신 구조를 결정한 경우 전체 구조를 읽을 때까지 읽지 않도록 설계 할 수 있습니다.

+0

답장을 보내 주셔서 감사하지만, 여전히 동일한 결과를 얻을. – user2136174

0

문제는 false로 비교하는 대신

if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) { 
    echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"; 
    break 2; 
} 

함께 === ''

if ('' === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) { 
    echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"; 
    break 2; 
} 

는 달리 연결이 조기에 종료되는 않는다 - 여기에서 볼 - http://www.php.net/manual/en/function.socket-read.php#89133

관련 문제