套接字php服务器没有显示从android客户端发送的消息

时间:2012-06-26 07:43:39

标签: php android sockets

嗨,我是这类东西的新手,但这就是我想做的事。

我正在尝试实现一个聊天应用程序,用户将从网站发送他们的查询,并且一旦网站用户发送消息。它将出现在网站所有者的Android移动应用程序中,他们将回答他们的问题查询。简而言之,我想实现一个实时聊天。

现在我只是想简单地尝试从Android应用程序发送消息到php服务器。 但是当我从chromeweaver中运行我的php脚本时,浏览器会继续加载,当我从客户端发送消息时,它不会显示任何输出。

有时它发生了php脚本显示我从android(客户端)发送的一些输出。但我不知道它何时起作用,何时不起作用。

所以我想在客户端发送这些消息后立即在php脚本中显示这些消息,反之亦然(对于客户端没有实现,反之亦然,但将不胜感激。)

这是我到目前为止所做的事情。

php脚本:

 <?php

 set_time_limit (0);
 $address = '127.0.0.1';

 $port = 1234;

 $sock = socket_create(AF_INET, SOCK_STREAM, 0);
 socket_bind($sock, $address, $port) or die('Could not bind to address');
 socket_listen($sock);


 $client = socket_accept($sock);
 $welcome = "Roll up, roll up, to the greatest show on earth!\n? ";
 socket_write($client, $welcome,strlen($welcome)) or die("Could not send connect string\n");

do{
$input=socket_read($client,1024,1) or die("Could not read input\n");
echo "User Says:  \n\t\t\t".$input;

if (trim($input) != "")
    { 
    echo "Received input: $input\n";
    if(trim($input)=="END")
    {
        socket_close($spawn);
        break;
    }
}
else{

$output = strrev($input) . "\n"; 
socket_write($spawn, $output . "? ", strlen (($output)+2)) or die("Could not write output\n");              
echo "Sent output: " . trim($output) . "\n";

}
}
while(true);


socket_close($sock);
echo "Socket Terminated";
?>

Android代码:

  public class ServerClientActivity extends Activity {
   private Button bt;
   private TextView tv;
   private Socket socket;
   private String serverIpAddress = "127.0.0.1";

   private static final int REDIRECTED_SERVERPORT = 1234;

   @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    bt = (Button) findViewById(R.id.myButton);
    tv = (TextView) findViewById(R.id.myTextView);

    try
    {
        InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
        socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
    } 
    catch (UnknownHostException e1) 
    {
        e1.printStackTrace();
    }
    catch (IOException e1)
    {
        e1.printStackTrace();
    }


    bt.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
           try
           {
              EditText et = (EditText) findViewById(R.id.EditText01);
              String str = et.getText().toString();
              PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
              out.println(str);
              Log.d("Client", "Client sent message");
           }
           catch (UnknownHostException e)
           {
              tv.setText(e.getMessage());
              e.printStackTrace();
           }
           catch (IOException e) 
           {
              tv.setText(e.getMessage());
              e.printStackTrace();
           }
           catch (Exception e) 
           {
              tv.setText(e.getMessage());
              e.printStackTrace();
           }
        }

     });       

   }
 }

我刚刚粘贴了针对Android.Edit的onclick按钮事件代码文本是我要输入文本的文本框。 ip地址和端口与php脚本相同。

4 个答案:

答案 0 :(得分:1)

首先 - 您的服务器一次只能处理一个客户端连接,这对聊天没有意义。

我无法看到你如何处理Android端的套接字连接,但无论如何,只要你的脚本执行不执行“ socket_accept()”并等待,它就不允许你再次连接用于连接。

您应该运行1个循环过程来获取新的客户端连接,并将每个连接的客户端分成单独的进程。

看一下我在这里写的基于相同原理的轻量级PHP服务器: https://github.com/webdevbyjoss/Aaaaa---space-ships-combat-multiplayer-game/blob/master/server/server.php

忽略与“ doHandshake()”和“ WebSocketFrame :: decode / WebSocketFrame :: encode ”相关的Websockets,但其他人应该没问题。

通常它会运行循环

while (true) 

    if (($msgsock = socket_accept ( $sock )) === false) {
        echo "socket_accept() failed: reason: " . socket_strerror ( socket_last_error ( $sock ) ) . "\n";
    break;
    }

    // We got a client connected, lets process it in separate thread
    if (($pid = pcntl_fork()) === -1) {
        echo "pcntl_fork() failed. Make sure you are on Linux sustem, but not on Windows\n";
        break;
    }

    if (!$pid) { // client
        handleClient($msgsock);
        exit();
    }

    // parent server will wait to accept more clients connections in new loop
}

handleClient()函数中,您应该有一个单独的循环来与客户端进行通信。

while (true) {
    if (false === ($buf = socket_read ( $msgsock, 2048, PHP_BINARY_READ ))) {
        echo "socket_read() failed: reason: " . socket_strerror ( socket_last_error ( $msgsock ) ) . "\n";
        return;
    }

    if (empty($buf)) { // do disconnection check
        echo "Client disconnected\n";
        return;
    }

   // -------------------------------------------------------------
   // PUT YOUR BUSINESS LOGIC HERE
   // TO HANDLE MESSAGES OF THE CHAT AND GENERATE RESPONSE TO USER
   // I RECOMMEND TO USE SOMETHING LIKE MEMCACHE/REDIS/MONGO/MYSQL/TXT-FILES
   // FOR MULTIPROCESS DATA INTERCHANGE
   // -------------------------------------------------------------

// transfer data to client
    socket_write($msgsock, $returnText, strlen($returnFrame));
}

socket_close ( $msgsock );

答案 1 :(得分:1)

我建议使用事件驱动的框架来处理您的连接。

有一个相当不错的例子称为React,但它有很多其他东西,你可能想要剥离,所以你的应用程序不依赖于数百个外部组件。

如果安装了libevent,则React会使用基于stream_select的消息循环,否则会使用 $client->on('read', function($data) use ($client) { $client->onRead($data); });

您使用闭包处理事件,例如:

{{1}}

通过这种方式,您将能够处理大量的并发连接,并且不会占用您的所有CPU。

当发生某些事情时,您的代码将会执行

如果没有别的,看看它是如何工作的,你将更好地理解如何创建一个非阻塞事件驱动的套接字服务器。

答案 2 :(得分:0)

您是否尝试在发送到服务器之前将'\ r \ n'添加到EditText的值中?我认为问题不是客户端和服务器之间的连接,因为它在连接失败时不显示错误。
也许在你的情况下 socket_read($ client,1024,1)必须停止阅读'\ r \ n'。

更新:您的本地IP可能会导致连接错误。看看this link

答案 3 :(得分:0)

您的地址127.0.0.1将解析为运行代码的计算机。所以应用程序实际上试图连接到自己。在MSDOS控制台上键入ipconfig /all并改为使用该地址。