如何使用socket在php中编写聊天程序服务器

时间:2016-07-23 15:13:05

标签: php python sockets

我在localhost上使用php作为服务器。 我使用python作为客户端。

我想要那样: 客户端将向服务器发送消息。 服务器将向客户端发送相同的消息。 并且所有客户端都将显示发送的消息。 但是当我打开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()

1 个答案:

答案 0 :(得分: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中。