이 기사에서는 PHP를 사용한 간단한 소켓 예제를 공유합니다. 입력 문자열을 수신하고 이 문자열을 처리하여 클라이언트에 반환하는 TCP 서비스를 구현합니다.
소켓 서버 생성
<?php /*文件名:socket_server.php*/ // 设置一些基本的变量 $host="127.0.0.1";//Socket运行的服务器的IP地址 $port=1234;//Socket运行的服务器的端口,端口取值为1到65535之间的数字,前提是这个端口未被使用 // 设置超时时间,这里设置为永不超时,确保PHP在等待客户端连接时不会超时。 set_time_limit(0); // 创建一个Socket,返回一个Socket句柄 $socket=socket_create(AF_INET,SOCK_STREAM,0) or die("Could not create socket\n"); //绑定Socket到指定的地址和端口 $result=socket_bind($socket,$host,$port) or die("Could not bind to socket\n"); // 开始监听外部连接 $result=socket_listen($socket,3) or die("Could not set up socket listener\n"); /******到这里,服务器除了等待来自客户端的连接请求外基本上什么也不做******/ // 另一个Socket来处理服务端与客户端的通信 $spawn=socket_accept($socket) or die("Could not accept incoming connection\n"); // 读取客户端的输入,当一个连接被建立后,服务器就会等待客户端发送一些输入信息,这些信息可以由socket_read()函数来获得,并把它赋值给PHP的$input变量 $input=socket_read($spawn,1024) or die("Could not read input\n"); //socker_read的第二个参数用以指定读入的字节数,你可以通过它来限制从客户端获取数据的大小 // 下面这不就不解释了,不知道的自己面壁去 $input=trim($input); //处理客户端输入并返回结果,当客户端发来数据信息后,信息输出就要靠socket_write()函数来完成 $output=strrev($input) ."\n";//反转字符串,这里仅仅是为了更好的区分两条信息 socket_write($spawn,$output,strlen($output)) or die("Could not write output\n"); // 关闭sockets socket_close($spawn); socket_close($socket);
팁: 위 코드를 실행하려면 명령 프롬프트를 사용해야 합니다. 그 이유는 여기에 웹페이지가 아닌 서버가 생성되기 때문이다. 웹 브라우저를 사용하여 이 스크립트를 실행하려고 하면 30초 제한을 초과할 가능성이 높습니다. 아래 코드를 사용하여 무한 런타임을 설정할 수 있지만 명령 프롬프트를 사용하여 실행하는 것이 좋습니다.
위의 서버측에는 세 가지 문제가 있습니다.
1. 다중 연결은 허용되지 않습니다.
2. 하나의 명령만 완료합니다.
3. 웹 브라우저를 통해 이 서버에 연결할 수 없습니다.
이 첫 번째 문제는 해결하기가 더 쉽습니다. 애플리케이션을 사용하여 매번 서버에 연결할 수 있습니다. 하지만 다음 문제는 서버에 연결하기 위해 웹 페이지를 사용해야 한다는 점인데, 이것이 더 어렵습니다. 서버가 연결을 수락하고 클라이언트에 일부 데이터를 쓰고(필요한 경우) 연결을 닫고 다음 연결을 기다리도록 할 수 있습니다.
이전 코드를 기반으로 개선하고 다음 코드를 생성하여 새 서버를 만듭니다.
<?php $commonProtocol = getprotobyname("tcp"); $socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol); socket_bind($socket, 'localhost', 1337); //socket_bind() 把socket绑定在一个IP地址和端口上 socket_listen($socket); $buffer = "NO DATA"; while(true) { // Accept any connections coming in on this socket $connection = socket_accept($socket);//socket_accept() 接受一个Socket连接 printf("Socket connected\r\n"); // Check to see if there is anything in the buffer if($buffer != ""){ printf("Something is in the buffer...sending data...\r\n"); socket_write($connection, $buffer . "\r\n"); //socket_write() 写数据到socket缓存 printf("Wrote to socket\r\n"); }else { printf("No Data in the buffer\r\n"); } // Get the input while($data = socket_read($connection, 1024, PHP_NORMAL_READ)){//socket_read() 读取指定长度的数据 $buffer = $data; socket_write($connection, "Information Received\r\n"); printf("Buffer: " . $buffer . "\r\n"); } socket_close($connection); //socket_close() 关闭一个socket资源 printf("Closed the socket\r\n\r\n"); }
이 서버는 무엇을 해야 합니까? 소켓을 초기화하고 캐시를 열어 데이터를 보내고 받습니다. 연결을 기다리고 연결이 이루어지면 서버 측 화면에 "소켓 연결됨"을 인쇄합니다. 이 서버는 버퍼를 확인하여 버퍼에 데이터가 있으면 연결된 컴퓨터로 데이터를 보냅니다. 그런 다음 이 데이터에 대한 수락 메시지를 보냅니다. 메시지를 수락하면 메시지를 데이터에 저장하고 연결된 컴퓨터가 메시지를 인식하게 한 다음 마지막으로 연결을 닫습니다. 연결이 닫히면 서버는 다음 연결 처리를 시작합니다.
소켓 클라이언트 생성
두 번째 문제를 처리하는 방법은 쉽습니다. PHP 페이지를 생성하고, 소켓에 연결하고, 일부 데이터를 캐시로 보내고 처리해야 합니다. 그런 다음 처리된 데이터가 대기 중이고 데이터를 서버로 보낼 수 있습니다. 다른 클라이언트 연결에서는 해당 데이터를 처리합니다.
다음 예에서는 소켓 사용을 보여줍니다.
<?php // Create the socket and connect $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $connection = socket_connect($socket,'localhost', 1337); while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)) { if($buffer == "NO DATA") { echo("<p>NO DATA</p>"); break; }else{ // Do something with the data in the buffer echo("<p>Buffer Data: " . $buffer . "</p>"); } } echo("<p>Writing to Socket</p>"); // Write some test data to our socket if(!socket_write($socket, "SOME DATA\r\n")){ echo("<p>Write failed</p>"); } // Read any response from the socket phpernote.com while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)){ echo("<p>Data sent was: SOME DATA<br> Response was:" . $buffer . "</p>"); } echo("<p>Done Reading from Socket</p>");
이 예제 코드는 서버에 연결하는 클라이언트를 보여줍니다. 클라이언트가 데이터를 읽습니다. 이것이 이 루프에 도달하는 첫 번째 연결인 경우 서버는 클라이언트에 "NO DATA"를 다시 보냅니다. 이런 일이 발생하면 클라이언트가 연결의 최상위에 있습니다. 클라이언트는 데이터를 서버로 보내고, 데이터는 서버로 전송되며, 클라이언트는 응답을 기다립니다. 응답을 받으면 화면에 응답을 씁니다.