Это не всегда происходит. Но это случается чаще, чем получение байтов полностью.
Вот как моя клиентская прога отправляет байты на мою серверную прогу:
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), только 1 из 4 попыток отправить файл на сервер увенчался успехом. при 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 () из программы, потому что я хочу поддерживать соединение клиентского приложения с сервером. Поэтому я хочу иметь возможность проверить, закончил ли я чтение всех байтов, поступающих из клиентского приложения, не закрывая сокетное соединение со стороны клиента.