我试图使用套接字发送文件..没有更多的字节文件工作......如何解决这个问题? 它是一个客户端/服务器程序 我试图发送至少50 MB。
客户端 - 发送:
System.Net.Sockets.TcpClient tcpClient = new
System.Net.Sockets.TcpClient();
tcpClient.Connect(recipientIP, FTPPORTNO);
int BufferSize = tcpClient.ReceiveBufferSize;
NetworkStream nws = tcpClient.GetStream();
FileStream fs;
fs = new FileStream(filename, FileMode.Open,
FileAccess.Read);
byte[] bytesToSend = new byte[fs.Length];
int numBytesRead = fs.Read(bytesToSend, 0,
bytesToSend.Length);
int totalBytes = 0;
for (int i = 0; i <= fs.Length/BufferSize; i++)
{
//---send the file---
if (fs.Length - (i*BufferSize) > BufferSize)
{
nws.Write(bytesToSend, i*BufferSize,
BufferSize);
totalBytes += BufferSize;
}
else
{
nws.Write(bytesToSend, i*BufferSize,
(int) fs.Length - (i*BufferSize));
totalBytes += (int) fs.Length - (i*BufferSize);
}
fs.Close();
}
接收代码:
try
{
//---get the local IP address---
System.Net.IPAddress localAdd =
System.Net.IPAddress.Parse(
ips.AddressList[0].ToString());
//---start listening for incoming connection---
System.Net.Sockets.TcpListener listener = new
System.Net.Sockets.TcpListener(localAdd,
FTPPORTNO);
listener.Start();
//---read incoming stream---
TcpClient tcpClient = listener.AcceptTcpClient();
NetworkStream nws = tcpClient.GetStream();
//---delete the file if it exists---
if (File.Exists("c:\\temp\\" + filename))
{
File.Delete("c:\\temp\\" + filename);
}
//---create the file---
fs = new System.IO.FileStream("c:\\temp\\" + filename,
FileMode.Append, FileAccess.Write);
int counter = 0;
int totalBytes = 0;
do
{
//---read the incoming data---
int bytesRead = nws.Read(data, 0,
tcpClient.ReceiveBufferSize);
totalBytes += bytesRead;
fs.Write(data, 0, bytesRead);
//---update the status label---
ToolStripStatusLabel1.Text = "Receiving " +
totalBytes + " bytes....";
Application.DoEvents();
counter += 1;
} while (nws.DataAvailable);
ToolStripStatusLabel1.Text = "Receiving " + totalBytes
+ " bytes....Done.";
fs.Close();
tcpClient.Close();
listener.Stop();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
服务器代码:
public void SendMessage (string message)
{
//---adds a linefeed char---
message += "\n";
try
{
//---send the text---
System.Net.Sockets.NetworkStream ns;
lock (client.GetStream())
{
ns = client.GetStream();
byte[] bytesToSend =
System.Text.Encoding.ASCII.GetBytes(message);
//---sends the text---
ns.Write(bytesToSend, 0, bytesToSend.Length);
ns.Flush();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
任何想法?
答案 0 :(得分:1)
您的主要问题是,您希望DataAvailable == false
表示不再有更多数据。事实并非如此。 DataAvailable
表示数据是否可用现在。这并不意味着将来某个时候不再可用。
如果您要发送和接收任何类型的数据,发送方必须有某种方式告诉接收方消息的结束位置。一般来说,有两种方法可以做到这一点:
使用文本协议时,通常使用第二个选项:发送消息,并使用换行符终止。这标志着信息的终结。
发送二进制数据时,通常使用第一种方法。该标题可以是简单的四个字节,表示文件的长度。所以在你的情况下,你会写一些类似的东西:
// tell receiver how many bytes are coming
byte[] lengthData = BitConverter.GetBytes[fs.Length];
nws.Write(lengthData, 0, lengthData.Length);
// then send the file
然后,接收器需要读取前四个字节,转换为整数,然后读取那么多字节。只有当它被读取时,许多字节才能知道它已到达文件的末尾。
// read length
byte[] lengthData = new byte[4];
bytesRead = nws.Read(lengthData, 0, 4);
// I assume here that it got all four bytes. In your code, you'll want to
// make sure that you got four bytes before moving on.
int bytesToRead = BitConverter.ToInt32(lengthData, 0);
// Now start your reading loop, and read until the total number of bytes read
// is equal to the bytesToRead value above.
答案 1 :(得分:0)
为什么不在发件人端执行此操作:
fileStream.CopyTo(networkStream);
更简单:)
在接收方,您不能认为DataAvailable = false
表示没有更多数据。完成socket.Shutdown(SocketShutdown.Send)
后发送方最好关闭连接,并且接收方继续读取直到0
返回。
发件人方:
socket.Shutdown(SocketShutdown.Send);
socket.Receive(xxx)
等待正常断开连接Socket.Close();
接收方:
socket.Shutdown(SocketShutdown.Both)
Socket.Close();
但是,您仍有一个缺陷:由于网络故障,套接字可能已断开连接。唯一知道的方法是先发送文件大小(在发送文件之前)