我有一个TCP连接,客户端是PHP
,服务器是C#
此套接字连接将图像传输到套接字
服务器,但是
随机有时传输会损坏[image hash
is different]
PHP 客户端
$file = file_get_contents('img.bmp');
socket_write($socket,$file.$cordinates); it sends //image + sme other data
$recv = socket_read ($socket, 500, PHP_BINARY_READ) // read the server response
这个流总是传输一个位图图像+一些数据。
C#
this.DataSocket = this.Listner.Accept();
int filelength = this.DataSocket.Receive(this.buffer, this.buffer.Length, SocketFlags.None)
我调查过,在 fresh-browser [newly opened] 中,这从未失败过。但是当我在同一个浏览器中频繁使用这个创建的服务时,这会失败。
当我检查一个不同的浏览器或浏览器的新实例时,它从未在前几次失败尝试。
我认为这是缓存
的一些问题,但我使用headers
禁用了缓存
,但同样的问题存在
最佳答案
您不能简单地期望一次将整个文件写入套接字,也不能期望在一次操作中从套接字读取文件。从 BSD 套接字到 WinSock 再到 .NET 网络类,几乎所有网络编程 API 的套接字读取和写入 API 都将传输或接收数据达到所需的字节数。
例如,如果您查看 PHP socket_write 的文档:
Returns the number of bytes successfully written to the socket or FALSE on failure. The error code can be retrieved with socket_last_error(). This code may be passed to socket_strerror() to get a textual explanation of the error.
Note: It is perfectly valid for socket_write() to return zero which means no bytes have been written. Be sure to use the == operator to check for FALSE in case of an error.
您通常需要选择一个 block 大小,如 4096 或 16384,然后循环传输或接收该 block 大小,直到您获得所需的传输或接收字节数。您的代码必须检查您正在调用的发送或接收函数的返回值,并相应地调整您的文件指针。如果传输返回 0,这可能只是意味着发送缓冲区已满(不是致命的)所以继续发送(可能需要 Sleep(0) 延迟)。如果 receive 返回 0,这通常意味着另一端已经干净地关闭了连接。
简单网络代码使用中最严重的缺陷之一是您在发送文件数据之前没有发送文件的大小,因此接收方无法知道在发送他们的文件之前要读取多少回复。对于像这样的简单操作,我建议只发送一个二进制 32 位整数(4 个字节)。这将是您的操作架构的一部分。因此接收方首先读取 4 个字节,然后知道还需要读取多少字节(一次一个缓冲区大小)。接收方不断读取,直到它们有那么多字节。
希望对您有所帮助。如果套接字代码像您尝试的用法一样简单,那就太好了,但不幸的是事实并非如此。您必须选择一个缓冲区大小,然后继续读取或写入该大小的缓冲区,直到获得您想要的为止,并且您必须向另一方传达您计划发送的数据量。
关于c# - PHP 到 C# - 套接字 - 文件随机损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6728776/