我的服务器程序接收的字节不完整.为什么?I';m使用C#.net套接字

本文关键字:使用 套接字 net 为什么 程序 服务器 字节 我的 | 更新日期: 2023-09-27 18:24:49

这种情况并不总是发生。但这种情况比完全接收字节更频繁。

这就是我的客户端程序向我的服务器程序发送字节的方式:

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);
}

这就是我的服务器程序从我的客户端程序接收字节的方式:

FileStream ms = new FileStream(tmpFile, FileMode.Create, FileAccess.Write);
do
{
    int szToRead = s.Available; //s is a socket
    byte[] buffer = new byte[szToRead];
    int szRead = s.Receive(buffer, szToRead, SocketFlags.None);
    if (szRead > 0)
        ms.Write(buffer, 0, szRead);            
}
while(s.Available != 0); //i also tried ms.length < size_of_file_to_be_received_in_bytes

我进入程序并查看了值,但我不知道是什么原因导致接收到的字节数不足。我不知道问题是客户端程序还是服务器程序。

我不知道这是否相关,但当我尝试进入客户端循环(观察fs.length的值并检查它是否会在服务器中接收)时,所有4次从客户端向服务器发送文件的尝试都成功了。但是,当我没有观察客户端循环,只观察服务器应用程序(查看ms.length的值)时,4次尝试向服务器发送文件中只有1次成功。在3次失败的尝试中,ms.length小于源文件的字节数(我在文件的属性中检查了它)。

这就是我从得出的结论

附加信息:

在原始代码(来自我基于程序的网站)上,循环有一个不同的条件:

FileStream ms = new FileStream(tmpFile, FileMode.Create, FileAccess.Write);
do
{
    int szToRead = s.Available; //s is a socket
    byte[] buffer = new byte[szToRead];
    int szRead = s.Receive(buffer, szToRead, SocketFlags.None);
    if (szRead > 0)
        ms.Write(buffer, 0, szRead);            
}
while(SocketConnected(s)); // <--- i changed this in my program
private static bool SocketConnected(Socket s)
{
    return !(s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0));
}

我认为SocketConnected测试套接字是否仍然连接,因为客户端程序的原始代码是这样的:

CopyStreamToStream(fs, ns, null);
ns.Flush();
ns.Close();

我去掉了ns。Close(),因为我想维护客户端应用程序与服务器的连接。因此,我希望能够在不关闭客户端套接字连接的情况下,检查是否已经读取完来自客户端应用程序的所有字节。

我的服务器程序接收的字节不完整.为什么?I';m使用C#.net套接字

如果Available为零,这并不意味着您已经完成读取字节。这意味着当前,在这纳秒内,没有字节排队。服务器怎么知道将来会有多少字节?

在很好的近似中,每一次使用Available都是一个错误!

删除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);
}