问题
I'm trying to send multiple files over TCP using C# TcpClient, for a single file it works great, but when I have multiple files, it sends only the first one.
Here is my code:
SENDING FILES
try
{
TcpClient tcpClient = new TcpClient();
NetworkStream networkStream;
FileStream fileStream = null;
tcpClient.Connect(appUpdateMessage.receiverIpAddress, 12000);
networkStream = tcpClient.GetStream();
byte[] byteSend = new byte[tcpClient.ReceiveBufferSize];
string startupPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6);
DirectoryInfo directoriesInfo = new DirectoryInfo(startupPath);
DirectoryInfo[] directories = directoriesInfo.GetDirectories();
FileInfo[] files = directoriesInfo.GetFiles();
for (int iLoop = 0; iLoop < directories.Length; iLoop++)
{
FileInfo[] subdirectoryFiles = directories[iLoop].GetFiles();
foreach (FileInfo fi in subdirectoryFiles)
{
fileStream = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read);
BinaryReader binFile = new BinaryReader(fileStream);
FileUpdateMessage fileUpdateMessage = new FileUpdateMessage();
fileUpdateMessage.fileName = fi.Name;
fileUpdateMessage.fileSize = fi.Length;
fileUpdateMessage.targetDirectory = fi.Directory.Name;
MessageContainer messageContainer = new MessageContainer();
messageContainer.messageType = MessageType.FileProperties;
messageContainer.messageContnet = SerializationManager.XmlFormatterObjectToByteArray(fileUpdateMessage);
byte[] messageByte = SerializationManager.XmlFormatterObjectToByteArray(messageContainer);
networkStream.Write(messageByte, 0, messageByte.Length);
int bytesSize = 0;
byte[] downBuffer = new byte[2048];
while ((bytesSize = fileStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
networkStream.Write(downBuffer, 0, bytesSize);
}
fileStream.Close();
}
}
tcpClient.Close();
networkStream.Close();
return true;
}
catch (Exception ex)
{
//logger.Info(ex.Message);
return false;
}
finally
{
}
RECEIVING FILES
try
{
TcpClient tcpClient = c as TcpClient;
NetworkStream networkstream = tcpClient.GetStream();
FileStream fileStream = null;
byte[] _data = new byte[1024];
int _bytesRead = 0;
_bytesRead = networkstream.Read(_data, 0, _data.Length);
MessageContainer messageContainer = new MessageContainer();
messageContainer = SerializationManager.XmlFormatterByteArrayToObject(_data, messageContainer) as MessageContainer;
switch (messageContainer.messageType)
{
case MessageType.FileProperties:
FileUpdateMessage fileUpdateMessage = new FileUpdateMessage();
fileUpdateMessage = SerializationManager.XmlFormatterByteArrayToObject(messageContainer.messageContnet, fileUpdateMessage) as FileUpdateMessage;
string startupPath = @"d:updatefolder";//System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6);
DirectoryInfo mainDirectory = new DirectoryInfo(startupPath);
DirectoryInfo targetDirecotry = new DirectoryInfo(startupPath + "\\" + fileUpdateMessage.targetDirectory);
if (!targetDirecotry.Exists)
{
mainDirectory.CreateSubdirectory(fileUpdateMessage.targetDirectory);
}
fileStream = new FileStream(startupPath + "\\" + fileUpdateMessage.targetDirectory + "\\" + fileUpdateMessage.fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
long filezie = fileUpdateMessage.fileSize;
int byteSize = 0;
byte[] downBuffer = new byte[2048];
while ((byteSize = networkstream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
fileStream.Write(downBuffer, 0, byteSize);
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
//progressBar1.Value = Convert.ToInt32((byteSize * 100) / fileUpdateMessage.fileSize);
progressBar1.Value = Convert.ToInt32((fileStream.Length * 100) / fileUpdateMessage.fileSize);
lblFileName.Text = fileUpdateMessage.fileName;
});
}
else
{
//progressBar1.Value = Convert.ToInt32((byteSize * 100) / fileUpdateMessage.fileSize);
lblFileName.Text = fileUpdateMessage.fileName;
}
}
fileStream.Close();
networkstream.Close();
break;
}
}
catch (Exception ex)
{
//logger.Error(ex.Message);
}
Any idea what I am doing wrong?
回答1:
you must close the stream after sending a file.
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.getstream%28v=vs.71%29.aspx
"Note You must close the NetworkStream when you are through sending and receiving data. Closing TcpClient does not release the NetworkStream."
回答2:
In your sending code, you've got a loop where you're sending multiple files. On the receiving side, I don't see a corresponding loop.
You could send the number of files that are about to be sent, and have the client loop that many times. You could also send something after the end of each file, which would indicate "Here comes another file" or "I'm done, close everything now".
回答3:
Short answer for this is, do it like ping-pong, send first file, let client reply, send again another file, let client reply and so-on.
来源:https://stackoverflow.com/questions/3625463/send-multiple-file-over-tcp-with-c-sharp-using-tcpclient