G
Guest
I am trying to us a simple NetworkStream to transfer a file over tcp. This
works most of the time, but one specific file never downloads(.mdb file). It
seems to close the socket and I get an "unable to write data to transport
connection" error. I have tried multiple ways to transfer this
file(including remoting, sockets without network stream) and downloaded
different examples of client/server byte transfer, all with the same result.
The file downloads around 705kb and stops. File size seems to have nothing
to do with it. The really strange thing is that if I reverse the bytes and
then send the file, it works, but the db is almost always corrupt on the
other side.
Here is the client:
using System;
using System.Diagnostics;
using System.Runtime.Remoting;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace C4I.FileTransfer
{
/// <summary>
/// Summary description for FileTransferClient.
/// </summary>
public class FileTransferClient
{
private int _instanceNumber;
private Socket clientSocket;
private bool _isReceiving = false;
public bool isReceiving{get{return _isReceiving;}}
private string _ipAddress;
private int _port;
public FileTransferClient(int instanceNumber, string ipAddress, int port)
{
_instanceNumber = instanceNumber;
_ipAddress = ipAddress;
_port = port;
}
int _fileLength;
string _fileName;
Thread receiveThread;
public void ReceiveFile(string fileName, int fileLength)
{
_fileName = fileName;
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
//clientSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);
IPHostEntry IPHost = Dns.Resolve(_ipAddress);
IPEndPoint endPoint = new IPEndPoint(IPHost.AddressList[0], _port);
clientSocket.Connect(endPoint);
receiveThread = new Thread(new ThreadStart(ReceiveFile));
receiveThread.Name = "Receive Thread";
_fileLength = fileLength;
receiveThread.Start();
}
private void ReceiveFile()
{
try
{
FileStream fs = null;
try
{
if (!File.Exists(_fileName))
fs = File.Create(_fileName);
else
fs = new FileStream(_fileName, FileMode.Create, FileAccess.ReadWrite);
int count = 0;
NetworkStream nfs = new NetworkStream(clientSocket);
while (count < _fileLength)
{
byte[] buffer = new byte[1024];
_isReceiving = true;
int i = nfs.Read(buffer, 0 , buffer.Length);
fs.Write(buffer, 0, (int)i);
count = count + i;
}
_isReceiving = false;
fs.Close();
}
catch (Exception exc)
{
Trace.WriteLine(exc.Message);
try
{
_isReceiving = false;
fs.Close();
}
catch{}
}
}
catch (Exception exc)
{
Trace.WriteLine(exc.Message);
_isReceiving = false;
}
}
}
and here is the server
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace C4I.FileTransfer
{
/// <summary>
/// Summary description for FileTransferServer.
/// </summary>
public class FileTransferServer
{
Socket _serverSocket;
Socket _clientSocket;
Thread listenThread;
string _ipAddress;
int _port;
public FileTransferServer(string ipAddress, int port)
{
_ipAddress = ipAddress;
_port = port;
listenThread =new Thread(new ThreadStart(ListenForClients));
listenThread.Name = "File Transfer listen thread";
listenThread.Start();
}
public void ListenForClients()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPHostEntry IPHost = Dns.Resolve(_ipAddress);
IPEndPoint endPoint = new IPEndPoint(IPHost.AddressList[0], _port);
_serverSocket.Blocking = true;
_serverSocket.Bind(endPoint);
_serverSocket.Listen(-1);
try
{
_clientSocket = _serverSocket.Accept();
}
catch{}
}
NetworkStream ns = null;
public void SendFile(string fileName)
{
if (_clientSocket == null || !_clientSocket.Connected)
{
End(false);
ListenForClients();
}
Thread.Sleep(1000);
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[1024];
ns = new NetworkStream(_clientSocket);
int count = 0;
int length = (int)fs.Length;
try
{
while (count < length && ns.CanWrite)
{
int bytesRead = fs.Read(buffer, 0, buffer.Length);
ns.Write(buffer, 0, bytesRead);
count += bytesRead;
}
}
catch
{
End(false);
ListenForClients();
}
finally
{
try
{
fs.Close();
}
catch{}
}
}
public void End(bool withDispose)
{
try{ns.Close();}
catch{}
try{_clientSocket.Shutdown(SocketShutdown.Both);}
catch{}
try{_clientSocket.Close();}
catch{}
try{_serverSocket.Close();}
catch{}
if (withDispose)
this.Dispose();
}
public void Dispose()
{
if (this.listenThread != null)
{
try
{
_serverSocket.Close();
}
catch{}
try
{
this.listenThread.Interrupt();
this.listenThread.Abort();
}
catch{}
this.listenThread = null;
}
}
}
}
works most of the time, but one specific file never downloads(.mdb file). It
seems to close the socket and I get an "unable to write data to transport
connection" error. I have tried multiple ways to transfer this
file(including remoting, sockets without network stream) and downloaded
different examples of client/server byte transfer, all with the same result.
The file downloads around 705kb and stops. File size seems to have nothing
to do with it. The really strange thing is that if I reverse the bytes and
then send the file, it works, but the db is almost always corrupt on the
other side.
Here is the client:
using System;
using System.Diagnostics;
using System.Runtime.Remoting;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace C4I.FileTransfer
{
/// <summary>
/// Summary description for FileTransferClient.
/// </summary>
public class FileTransferClient
{
private int _instanceNumber;
private Socket clientSocket;
private bool _isReceiving = false;
public bool isReceiving{get{return _isReceiving;}}
private string _ipAddress;
private int _port;
public FileTransferClient(int instanceNumber, string ipAddress, int port)
{
_instanceNumber = instanceNumber;
_ipAddress = ipAddress;
_port = port;
}
int _fileLength;
string _fileName;
Thread receiveThread;
public void ReceiveFile(string fileName, int fileLength)
{
_fileName = fileName;
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
//clientSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, 1);
IPHostEntry IPHost = Dns.Resolve(_ipAddress);
IPEndPoint endPoint = new IPEndPoint(IPHost.AddressList[0], _port);
clientSocket.Connect(endPoint);
receiveThread = new Thread(new ThreadStart(ReceiveFile));
receiveThread.Name = "Receive Thread";
_fileLength = fileLength;
receiveThread.Start();
}
private void ReceiveFile()
{
try
{
FileStream fs = null;
try
{
if (!File.Exists(_fileName))
fs = File.Create(_fileName);
else
fs = new FileStream(_fileName, FileMode.Create, FileAccess.ReadWrite);
int count = 0;
NetworkStream nfs = new NetworkStream(clientSocket);
while (count < _fileLength)
{
byte[] buffer = new byte[1024];
_isReceiving = true;
int i = nfs.Read(buffer, 0 , buffer.Length);
fs.Write(buffer, 0, (int)i);
count = count + i;
}
_isReceiving = false;
fs.Close();
}
catch (Exception exc)
{
Trace.WriteLine(exc.Message);
try
{
_isReceiving = false;
fs.Close();
}
catch{}
}
}
catch (Exception exc)
{
Trace.WriteLine(exc.Message);
_isReceiving = false;
}
}
}
and here is the server
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace C4I.FileTransfer
{
/// <summary>
/// Summary description for FileTransferServer.
/// </summary>
public class FileTransferServer
{
Socket _serverSocket;
Socket _clientSocket;
Thread listenThread;
string _ipAddress;
int _port;
public FileTransferServer(string ipAddress, int port)
{
_ipAddress = ipAddress;
_port = port;
listenThread =new Thread(new ThreadStart(ListenForClients));
listenThread.Name = "File Transfer listen thread";
listenThread.Start();
}
public void ListenForClients()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPHostEntry IPHost = Dns.Resolve(_ipAddress);
IPEndPoint endPoint = new IPEndPoint(IPHost.AddressList[0], _port);
_serverSocket.Blocking = true;
_serverSocket.Bind(endPoint);
_serverSocket.Listen(-1);
try
{
_clientSocket = _serverSocket.Accept();
}
catch{}
}
NetworkStream ns = null;
public void SendFile(string fileName)
{
if (_clientSocket == null || !_clientSocket.Connected)
{
End(false);
ListenForClients();
}
Thread.Sleep(1000);
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[1024];
ns = new NetworkStream(_clientSocket);
int count = 0;
int length = (int)fs.Length;
try
{
while (count < length && ns.CanWrite)
{
int bytesRead = fs.Read(buffer, 0, buffer.Length);
ns.Write(buffer, 0, bytesRead);
count += bytesRead;
}
}
catch
{
End(false);
ListenForClients();
}
finally
{
try
{
fs.Close();
}
catch{}
}
}
public void End(bool withDispose)
{
try{ns.Close();}
catch{}
try{_clientSocket.Shutdown(SocketShutdown.Both);}
catch{}
try{_clientSocket.Close();}
catch{}
try{_serverSocket.Close();}
catch{}
if (withDispose)
this.Dispose();
}
public void Dispose()
{
if (this.listenThread != null)
{
try
{
_serverSocket.Close();
}
catch{}
try
{
this.listenThread.Interrupt();
this.listenThread.Abort();
}
catch{}
this.listenThread = null;
}
}
}
}