.NET C#通过本地TCP连接到PHP

.NET C#通过本地TCP连接到PHP,c#,php,.net,sockets,tcpclient,C#,Php,.net,Sockets,Tcpclient,我有一个.NETC#控制台应用程序作为客户端,一个PHP脚本作为服务器。两者都通过localhost连接,因此不存在互联网速度依赖性。我遇到的问题是,当我的客户端应用程序发送一个二进制文件时,比如说仅100KB,需要大约30秒才能完成。我希望这个过程几乎是瞬间的 下面是一些代码: .NET客户端应用程序: public bool SendToServer(string data) { data += "DONE"; // Terminator string TcpClient t

我有一个.NETC#控制台应用程序作为客户端,一个PHP脚本作为服务器。两者都通过
localhost
连接,因此不存在互联网速度依赖性。我遇到的问题是,当我的客户端应用程序发送一个二进制文件时,比如说仅100KB,需要大约30秒才能完成。我希望这个过程几乎是瞬间的

下面是一些代码:

.NET客户端应用程序:

public bool SendToServer(string data)
{
    data += "DONE"; // Terminator string
    TcpClient tcp = new TcpClient(this.serverURL, this.serverPort);
    NetworkStream stream = tcp.GetStream();
    byte[] b = Encoding.ASCII.GetBytes(data);
    int len = b.Length;
    for (int i = 0; i < len; i++)
        stream.Write(b, i, 1);
    stream.Flush();

    Console.WriteLine("Sent to server {0}", Convert.ToString(b) + " len: " + b.Length);
    return true;
}

查看了PHP代码后,我怀疑这实际上是速度问题的原因:

do{
    $buf .= fread($con, 1);
    if(strlen($buf) == 0) break 2;
}
while(substr($buf, -4) != "DONE");
假设PHP的工作方式与Java和.NET相同(即假设
=
创建了一个包含先前数据副本的新字符串),那么您将为每个字节创建一个新字符串。。。这是一个O(n^2)操作,很快就会变得很糟糕

此外:

  • 如果您在原始数据中“完成”,则您的协议将被破坏
  • 您的协议专门处理文本,而不是二进制数据。有可能您是先对二进制数据进行base64编码(给定PHP),但这也是低效的。如果您确实拥有二进制数据,那么最好将其作为二进制数据传输。套接字完全能够做到这一点——除非您的问题域特别需要文本,否则根本没有理由让文本参与其中

我建议您首先将数据的长度写入套接字,作为4或8字节的整数(取决于您是否认为需要传输超过4GB的数据)。然后,您可以先读取PHP代码中的长度,分配一个适当大小的缓冲区,然后继续从套接字读取该缓冲区(一次读取一大块),直到完成为止。这将更加高效,不会出现上述协议问题。

查看了您的PHP代码后,我怀疑这实际上是速度问题的原因:

do{
    $buf .= fread($con, 1);
    if(strlen($buf) == 0) break 2;
}
while(substr($buf, -4) != "DONE");
假设PHP的工作方式与Java和.NET相同(即假设
=
创建了一个包含先前数据副本的新字符串),那么您将为每个字节创建一个新字符串。。。这是一个O(n^2)操作,很快就会变得很糟糕

此外:

  • 如果您在原始数据中“完成”,则您的协议将被破坏
  • 您的协议专门处理文本,而不是二进制数据。有可能您是先对二进制数据进行base64编码(给定PHP),但这也是低效的。如果您确实拥有二进制数据,那么最好将其作为二进制数据传输。套接字完全能够做到这一点——除非您的问题域特别需要文本,否则根本没有理由让文本参与其中

我建议您首先将数据的长度写入套接字,作为4或8字节的整数(取决于您是否认为需要传输超过4GB的数据)。然后,您可以先读取PHP代码中的长度,分配一个适当大小的缓冲区,然后继续从套接字读取该缓冲区(一次读取一大块),直到完成为止。这将更加高效,不会出现上述协议问题。

查看了您的PHP代码后,我怀疑这实际上是速度问题的原因:

do{
    $buf .= fread($con, 1);
    if(strlen($buf) == 0) break 2;
}
while(substr($buf, -4) != "DONE");
假设PHP的工作方式与Java和.NET相同(即假设
=
创建了一个包含先前数据副本的新字符串),那么您将为每个字节创建一个新字符串。。。这是一个O(n^2)操作,很快就会变得很糟糕

此外:

  • 如果您在原始数据中“完成”,则您的协议将被破坏
  • 您的协议专门处理文本,而不是二进制数据。有可能您是先对二进制数据进行base64编码(给定PHP),但这也是低效的。如果您确实拥有二进制数据,那么最好将其作为二进制数据传输。套接字完全能够做到这一点——除非您的问题域特别需要文本,否则根本没有理由让文本参与其中

我建议您首先将数据的长度写入套接字,作为4或8字节的整数(取决于您是否认为需要传输超过4GB的数据)。然后,您可以先读取PHP代码中的长度,分配一个适当大小的缓冲区,然后继续从套接字读取该缓冲区(一次读取一大块),直到完成为止。这将更加高效,不会出现上述协议问题。

查看了您的PHP代码后,我怀疑这实际上是速度问题的原因:

do{
    $buf .= fread($con, 1);
    if(strlen($buf) == 0) break 2;
}
while(substr($buf, -4) != "DONE");
假设PHP的工作方式与Java和.NET相同(即假设
=
创建了一个包含先前数据副本的新字符串),那么您将为每个字节创建一个新字符串。。。这是一个O(n^2)操作,很快就会变得很糟糕

此外:

  • 如果您在原始数据中“完成”,则您的协议将被破坏
  • 您的协议专门处理文本,而不是二进制数据。有可能您是先对二进制数据进行base64编码(给定PHP),但这也是低效的。如果您确实拥有二进制数据,那么最好将其作为二进制数据传输。套接字完全能够做到这一点——除非您的问题域特别需要文本,否则根本没有理由让文本参与其中

我建议您首先将数据的长度写入套接字,作为4或8字节的整数(取决于您是否认为需要传输超过4GB的数据)。然后,您可以先读取PHP代码中的长度,分配一个适当大小的缓冲区,然后继续从套接字读取该缓冲区(一次读取一大块),直到完成为止。这样会更有效率,不会出现上述协议问题。

您应该一次写入整个数组,而不是一次写入一个字节。您一次写入一个字节,