我正在开发一个c#和php项目,其中PHP脚本打开一个c#程序的套接字,c#程序将读取数据,然后发回一个响应。
在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#app上的套接字发送回应但我不知道如何做到这一点。另一个问题,在C#中我需要Console.ReadLine()
,否则c#程序将退出,但PHP脚本会按预期完成。
基本上,我想知道的是这是读取套接字上发送的数据的最佳方法,保持程序运行的最佳方法是什么,以便继续监听套接字以及如何发送回来回复以便php脚本可以完成。
感谢您提供的任何帮助。
答案 0 :(得分:4)
我设法解决了这个问题,在处理完数据后我需要发送一个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();
}
感谢您的帮助
答案 1 :(得分: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);
}
答案 2 :(得分:0)
我不是任何想象力的PHP家伙所以我的答案取决于php能够正确回应。在C#端,创建一个while / do-while循环,继续运行以接受下一个传入请求。这是一个简单的例子:
http://www.csharp-examples.net/socket-send-receive/
确保设置NoDelay选项以便刷新信息。