2016-07-23 32 views
0

我在本地主機上使用php作爲服務器。 我使用python作爲客戶端。如何在php中使用socket編寫聊天程序的服務器

我想: 客戶端將發送消息到服務器。 服務器將向客戶端發送相同的消息。 所有的客戶端都會顯示發送的消息。 但是,當我打開2個客戶端時,客戶端在發送消息時無法從服務器獲得答案。

我怎樣才能寫一個服務器與PHP的工作是否正確? 有什麼想法?

server.php:

<?php 

    error_reporting(E_ALL); 

    set_time_limit(0); 

    header("Content-Type: text/plain; charset=UTF-8"); 

    define("HOST", "127.0.0.1"); 

    define("PORT", 28028); 
a:  
    $socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n"); 
    $result = socket_bind($socket, HOST, PORT) or die("Could not bind to socket\n"); 
    $result = socket_listen($socket, 50) or die("Could not set up socket listener\n"); 

    $error = 0; 
    while (true){ 
     $error = 0; 
     $spawn = socket_accept($socket) or die("Could not accept incoming connection\n"); 
     $input = socket_read($spawn, 1024); 
     if (!$input) { 
      $error = 1; 
     } 


     if (socket_write($spawn, $input, strlen($input)) === false){ 
      $error = 1; 
     } 

     if ($error){ 
      goto a; 
     } 



    } 
    socket_close($spawn); 

    socket_close($socket); 

client.py:

from socket import * 
from threading import Thread 
import sys 

HOST = 'localhost' 
PORT = 28028 
BUFSIZE = 1024 
ADDR = (HOST, PORT) 

tcpCliSock = socket(AF_INET, SOCK_STREAM) 
tcpCliSock.connect(ADDR) 

def recv(): 
    while True: 
     data = tcpCliSock.recv(BUFSIZE) 
     if not data: sys.exit(0) 
     print data 

Thread(target=recv).start() 
while True: 
    data = raw_input('> ') 
    if not data: break 
    tcpCliSock.send(data) 

tcpCliSock.close() 

回答

0

該服務器具有同時等待來自客戶機的連接和數據;這很容易與socket_select()。更換你while (true){…}循環與

$s = array($socket); // initially wait for connections 
    while ($r = $s and socket_select($r, $n=NULL, $n=NULL, NULL)) 
    foreach ($r as $stream) 
    if ($stream == $socket) // new client 
     $s[] = socket_accept($socket);    // add it to $s (index 1 on) 
    else     // data from a client 
     if ($input = socket_read($stream, 1024)) 
      foreach (array_slice($s, 1) as $client) // clients from index 1 on 
       socket_write($client, $input, strlen($input)); 
     else 
     { 
      close($stream); 
      array_splice($s, array_search($stream, $s), 1); // remove client 
     } 

這裏的服務器套接字和客戶端套接字存儲在陣列$s英寸

相關問題