我的服务器程序接收的字节不完整。为什么?I';我使用C#.net套接字
这种情况并不总是发生。但这种情况比完全接收字节更为常见 这是我的客户端程序将字节发送到服务器程序的方式:我的服务器程序接收的字节不完整。为什么?I';我使用C#.net套接字,c#,sockets,filestream,C#,Sockets,Filestream,这种情况并不总是发生。但这种情况比完全接收字节更为常见 这是我的客户端程序将字节发送到服务器程序的方式: public void sendBytes() { FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); TcpClient cli = tcpServer; //tcpServer is a global TcpClient variabl
public void sendBytes()
{
FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
TcpClient cli = tcpServer; //tcpServer is a global TcpClient variable I use to connect to the server.
NetworkStream ns = cli.GetStream();
CopyStreamToStream(fs, ns, null);
ns.Flush();
}
public static void CopyStreamToStream(Stream source, Stream destination, Action<Stream, Stream, Exception> completed)
{
byte[] buffer = new byte[0x1000];
int read;
while ((read = source.Read(buffer, 0, buffer.Length)) > 0) // <- client loop
destination.Write(buffer, 0, read);
}
我从程序中删除了ns.Close(),因为我想保持客户端应用程序与服务器的连接。因此,我希望能够在不关闭客户端套接字连接的情况下检查是否已读取完客户端应用程序中的所有字节。如果可用值为零,这并不意味着您已读取完字节。这意味着目前,在这纳秒内,没有字节排队。服务器如何知道将来会有多少字节 在很好的近似下,每一次可用的使用都是错误的 删除可用的所有用法。相反,总是尝试读取一个完整的缓冲区。如果得到0,则表示套接字已关闭,您已完成 编辑:以下是一些规范的读取代码:
var buffer = new byte[8192];
while(true) {
var readCount = stream.Read(buffer, 0, buffer.Length);
if (readCount == 0) break;
outputStream.Write(buffer, 0, readCount);
}
如果Available为零,这并不意味着您已完成读取字节。这意味着目前,在这纳秒内,没有字节排队。服务器如何知道将来会有多少字节 在很好的近似下,每一次可用的使用都是错误的 删除可用的所有用法。相反,总是尝试读取一个完整的缓冲区。如果得到0,则表示套接字已关闭,您已完成 编辑:以下是一些规范的读取代码:
var buffer = new byte[8192];
while(true) {
var readCount = stream.Read(buffer, 0, buffer.Length);
if (readCount == 0) break;
outputStream.Write(buffer, 0, readCount);
}
您是否考虑过使用
Stream.CopyTo()
[假设您使用的是.NET 4.0]?我建议您使用而不是copyreamtostream
函数。我将对此进行研究。谢谢您的建议。您是否考虑过使用Stream.CopyTo()
[假设您使用的是.NET 4.0]?我建议您使用而不是copyreamtostream
函数。我将对此进行研究。谢谢你的建议。@usr我很抱歉。我不确定我应该如何“读取一个完整的缓冲区”。你能提供一个关于如何做到这一点的示例代码吗?在我的代码中,我有:do{if(szRead>0)ms.Write(buffer,0,szRead);}while(s.Available!=0)我把它改成:do{if(szRead>0)ms.Write(buffer,0,szRead);else break;}while(true)代码>行吗?试试看。至少你摆脱了我讨厌的东西。我想你可以接受我的密码。它应该可以工作。不久前,我制作了一个简单的套接字应用程序,因为我记得通过套接字发送的最后一个字节是\0这是通过连接发送的字节数组的终止符否,这意味着不能通过套接字发送任意数据。任何数据都可以发送。长度/终止信息必须由应用程序本身编码。@usr很抱歉。我不确定我应该如何“读取一个完整的缓冲区”。你能提供一个关于如何做到这一点的示例代码吗?在我的代码中,我有:do{if(szRead>0)ms.Write(buffer,0,szRead);}while(s.Available!=0)我把它改成:do{if(szRead>0)ms.Write(buffer,0,szRead);else break;}while(true)代码>行吗?试试看。至少你摆脱了我讨厌的东西。我想你可以接受我的密码。它应该可以工作。不久前,我制作了一个简单的套接字应用程序,因为我记得通过套接字发送的最后一个字节是\0这是通过连接发送的字节数组的终止符否,这意味着不能通过套接字发送任意数据。任何数据都可以发送。长度/终止信息必须由应用程序本身编码。
CopyStreamToStream(fs, ns, null);
ns.Flush();
ns.Close();
var buffer = new byte[8192];
while(true) {
var readCount = stream.Read(buffer, 0, buffer.Length);
if (readCount == 0) break;
outputStream.Write(buffer, 0, readCount);
}