【发布时间】:2014-03-25 03:21:46
【问题描述】:
我有一个充当客户端的 .NET C# 控制台应用程序和一个充当服务器的 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 服务器脚本:
class ImageService
{
public $ip, $port, $soc;
function Listen($ip, $port)
{
$this->ip = $ip;
$this->port = $port;
$this->soc = stream_socket_server("tcp://".$this->ip.":".$this->port, $errno, $errstr);
if(!$this->soc) Out($errno);
else
{
Out("created socket");
$buf = "";
while($con = stream_socket_accept($this->soc))
{
Out("accepted socket");
do{
$buf .= fread($con, 1);
if(strlen($buf) == 0) break 2;
}
while(substr($buf, -4) != "DONE");
$buf = substr($buf, 0, strlen($buf) - 4);
switch($buf)
{
case "quit":
break 2;
}
print '<img alt="image" src="data:image/jpeg;base64,'.$buf.'">';
$buf = "";
}
fclose($con);
fclose($this->soc);
Out("Closed connection");
}
}
}
来电:
set_time_limit(0);
//error_reporting(E_ALL);
$is = new ImageService();
$is->Listen("127.0.0.1", 1234);
【问题讨论】:
-
您应该一次写入整个数组,而不是一次写入一个字节。
-
你一次写一个字节,这没有帮助。为什么不直接使用
stream.Write(b, 0, b.Length);?如果您的字符串曾经包含“DONE”,并且无法处理非 ASCII 字符,那么您的协议也会失败,但这不是速度问题... -
更重要的是,二进制文件不是ASCII。除非您确实有文本,否则不要使用字符串。
-
@JonSkeet 我可能会发送可能只有几 MB 的图像文件,如果按照你说的做没有问题,那么我肯定会更改代码。另外,如果我一次只做一个字节,我可以根据总长度来衡量进度。 SLaks 我认为 ASCII 会使二进制文件安全传输,不是这样吗?
-
@Lee:100,000 个单字节调用肯定不如单个 100K 字节调用好,尤其是当您已经拥有内存中的所有数据时。在 ASCII 方面,不,当然不是这样。如果您尝试传输二进制数据,则根本不应该让您的方法接受
string参数。见msmvps.com/blogs/jon_skeet/archive/2013/06/21/…
标签: c# php .net sockets tcpclient