2

PHPスクリプトがac#プログラムへのソケットを開き、c#プログラムがデータを読み取ってから応答を返すac#およびphpプロジェクトに取り組んでいます。

PHPスクリプトには、次のものがあります。

echo "Opening Client";

$fp = fsockopen("127.0.0.1", 12345, $errno, $errstr, 30);

if (!$fp)
{
    echo "Error: $errstr ($errno)<br />";
}
else
{
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: 127.0.0.1\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp))
    {
        echo fgets($fp, 128);
    }
    fclose($fp);
}

C# プロジェクトには、次のものがあります。

public void startListen()
        {
            int port = 12345;
            IPAddress serverAddress = IPAddress.Parse("127.0.0.1");
            TcpListener listener = new TcpListener(serverAddress, 12345);
            listener.Start();

            TcpClient client = listener.AcceptTcpClient();

            NetworkStream stream = client.GetStream();
            byte[] data = new byte[client.ReceiveBufferSize];
            int bytesRead = stream.Read(data, 0, Convert.ToInt32(client.ReceiveBufferSize));
            string request = Encoding.ASCII.GetString(data, 0, bytesRead);
            Console.WriteLine(request);

            Console.ReadLine();

PHPスクリプトは待機しているようで終了しません.C#アプリのソケットが応答を返すためだと思いますが、これを行う方法がわかりません. もう 1 つの問題は、C# で必要な場合ですConsole.ReadLine()。それ以外の場合、C# プログラムは終了しますが、PHP スクリプトは期待どおりに終了します。

基本的に、私が知りたいのは、これがソケットで送信されたデータを読み取る最良の方法であり、プログラムを実行し続けてソケットでリッスンし続けるための最良の方法と、応答を返す方法です。 php スクリプトを終了できます。

ご協力いただきありがとうございます。

4

3 に答える 3

5

私はこれを理解することができました。データを処理した後、返信を返すstream.writeを送信する必要があります。

以下はコードです

            int port = 12345;
            IPAddress serverAddress = IPAddress.Parse("127.0.0.1");
            TcpListener listener = new TcpListener(serverAddress, port);
            listener.Start();

            while (true)
            {
                TcpClient client = listener.AcceptTcpClient();

                NetworkStream stream = client.GetStream();
                byte[] data = new byte[client.ReceiveBufferSize];
                int bytesRead = stream.Read(data, 0, Convert.ToInt32(client.ReceiveBufferSize));
                string request = Encoding.ASCII.GetString(data, 0, bytesRead);
                Console.WriteLine(request);
                byte[] msg = System.Text.Encoding.ASCII.GetBytes("200 OK");

                // Send back a response.
                stream.Write(msg, 0, msg.Length);
                client.Close();
            }

ご協力いただきありがとうございます

于 2012-05-29T22:50:03.557 に答える
2

Boardy氏の解決策は正しいですが、ソケットでこれを行う方が良いと思います。

したがって、ソケットソリューションは次のとおりです。

private void Form3_Load(object sender, EventArgs e)
{
    sc_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    IPEndPoint ip_local = new IPEndPoint(IPAddress.Loopback, 1225);
    sc_listener.Bind(ip_local);
    sc_listener.Listen(10);

    AsyncCallback callback = new AsyncCallback(procces_incoming_socket);
    sc_listener.BeginAccept(callback, sc_listener);
}

void procces_incoming_socket(IAsyncResult socket_object)
{
    Socket sc_listener = ((Socket)socket_object.AsyncState).EndAccept(socket_object);

    AsyncCallback receive = new AsyncCallback(receive_data);
    buffer = new byte[100];
    sc_listener.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, receive, sc_listener);
}

void receive_data(IAsyncResult socket)
{
    // the system need to wait so i make a loop when it gets data 
    //i end the loop by flag=false
    bool flag = true;
    Socket re_socket = ((Socket)socket.AsyncState);
    while(flag)
    {
        int bytes_recieved = re_socket.EndReceive(socket);

        string data = UTF8Encoding.UTF8.GetString(buffer);
        if (textBox1.InvokeRequired)
        {
            // for cross thread problem
            textBox1.Invoke(new MethodInvoker(delegate { textBox1.Text = data; }));
        }
        else
        {
            textBox1.Text = data;
        }
        flag = false;
    }
    string back_data = "my pm socket back";
    byte[] buffers = new byte[50];
    buffers = UTF8Encoding.UTF8.GetBytes(back_data);
    re_socket.Send(buffers);
    // if the socket is not closed php will load for maximum required time and then error
    re_socket.Close();
    //start for next listening (O-0)
    AsyncCallback callback = new AsyncCallback(procces_incoming_socket);
    sc_listener.BeginAccept(callback, sc_listener);
}
于 2015-09-25T01:41:20.553 に答える
0

私はどう考えても PHP の専門家ではないので、答えは PHP が正しく応答できるかどうかにかかっています。C# 側で、実行を継続して次の着信要求を受け入れる while/do-while ループを作成します。簡単な例を次に示します。

http://www.csharp-examples.net/socket-send-receive/

情報がフラッシュされるように、必ず NoDelay オプションを設定してください。

于 2012-05-29T21:06:50.307 に答える