通过套接字在 C# 中传输一半文件?
Half file transferring in c# via socket?
我正在通过中级贪婪路由开发文件传输应用程序,其中文件发送到贪婪,贪婪再次将文件发送到路由器
但他的问题是有时客户端会收到完整的文件,有时会收到文件的一部分
这是我的代码
服务器端
IPAddress[] ipAddress = Dns.GetHostAddresses("127.0.0.1");
IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5655);
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
string filePath = "";
fileDes = fileDes.Replace("\", "/");
while (fileDes.IndexOf("/") > -1)
{
filePath += fileDes.Substring(0, fileDes.IndexOf("/") + 1);
fileDes = fileDes.Substring(fileDes.IndexOf("/") + 1);
}
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileDes);
lblError.Text = "";
lblError.Text = "Buffering ...";
byte[] fileData = File.ReadAllBytes(filePath + fileDes);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
lblError.Text = "";
lblError.Text = "Connection to server ...";
clientSock.Connect(ipEnd);
lblError.Text = "";
lblError.Text = "File sending...";
// System.Threading.Thread.Sleep(1000);
clientSock.Send(clientData);
label3.Text = clientData.Length.ToString();
lblError.Text = "";
lblError.Text = "Disconnecting...";
clientSock.Close();
lblError.Text = "";
lblError.Text = "File transferred.";
在客户端
class DestCode
{
IPEndPoint ipEnd;
Socket sock;
public DestCode()
{
ipEnd = new IPEndPoint(IPAddress.Any, 5656);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
}
public static string receivedPath;
public static string curMsg = "Stopped";
public static int res;
public void StartServer()
{
try
{
curMsg = "Starting...";
sock.Listen(100);
curMsg = "Running and waiting to receive file.";
Socket clientSock = sock.Accept();
byte[] clientData = new byte[1024 * 5000];
int receivedBytesLen = clientSock.Receive(clientData);
curMsg = "Receiving data...";
int fileNameLen = BitConverter.ToInt32(clientData, 0);
string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);
BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath +"/"+ fileName, FileMode.Append)); ;
bWrite.Write(clientData,4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
res = receivedBytesLen;
if (receivedPath == "")
{
MessageBox.Show("No Path was selected to Save the File");
}
curMsg = "Saving file...";
bWrite.Close();
clientSock.Close();
curMsg = "File Received ...";
StartServer();
}
catch (Exception ex)
{
curMsg = "File Receving error.";
}
}
}
贪心
class ReceiverCode
{
IPEndPoint ipEnd;
Socket sock;
public ReceiverCode()
{
ipEnd = new IPEndPoint(IPAddress.Any, 5655);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
}
public static string receivedPath;
public static string curMsg = "Stopped";
public static string Rout = "";
public static int rlength = 0;
public static string MsgStatus = "";
public static byte[] send;
public void StartServer()
{
try
{
curMsg = "Starting...";
sock.Listen(100);
curMsg = "Running and waiting to receive file.";
Socket clientSock = sock.Accept();
byte[] clientData = new byte[1024 * 5000];
int receivedBytesLen = clientSock.Receive(clientData);
System.Threading.Thread.Sleep(5000);
rlength = receivedBytesLen;
curMsg = "Receiving data...";
int receive = clientSock.Receive(clientData);
send = new byte[receivedBytesLen];
Array.Copy(clientData, send, receivedBytesLen);
Rout = "Start";
clientSock.Close();
curMsg = "Reeived & Saved file; Server Stopped.";
StartServer();
}
catch (Exception ex)
{
curMsg = "File Receving error.";
}
}
}
请有人帮助我
问题是 Socket.Receive
不能保证您会收到您要求的所有字节。所以你写:
int receivedBytesLen = clientSock.Receive(clientData);
If you are using a connection-oriented Socket, the Receive method will read as much data as is available, up to the size of the buffer.
对 Receive
的调用正在获取当前可用的所有字节。可能是发件人尚未发送所有字节,或者您的网络堆栈尚未收到并使它们可用。
为了可靠地发送和接收数据,接收方必须知道以下两件事之一:它期望有多少字节,或者有一些标记值表明,"that's all, folks." 你不能指望一次 Receive
调用即可获取所有内容。
传输文件时,发件人通常将文件的大小作为要发送的数据的前四个字节。然后您的代码读取前四个字节(确保您获得所有四个字节)以确定大小,然后旋转一个循环,从套接字读取数据,直到收到所有预期的字节。
类似于:
const int MaximumSize = 1000000;
// read the first four bytes
var sizeBytes = ReadBytesFromSocket(socket, 4);
int size = BitConverter.ToInt32(sizeBytes);
var dataBuffer = ReadBytesFromSocket(socket, size);
// you now have your data
byte[] ReadBytesFromSocket(Socket socket, int size)
{
var buff = new byte[size];
int totalBytesRead = 0;
while (totalBytesRead < size)
{
int bytesRead = socket.Receive(buff, totalBytesRead, size-totalBytesRead, SocketFlags.None);
if (bytesRead == 0)
{
// nothing received. The socket has been closed.
// maybe an error.
break;
}
totalBytesRead += bytesRead
}
return buff;
}
有关详细信息,请参阅我在 reading streams 上的博客 post(以及链接的第 1 部分和第 2 部分)。博客 post 讨论流,但概念与套接字相同。
我正在通过中级贪婪路由开发文件传输应用程序,其中文件发送到贪婪,贪婪再次将文件发送到路由器 但他的问题是有时客户端会收到完整的文件,有时会收到文件的一部分
这是我的代码 服务器端
IPAddress[] ipAddress = Dns.GetHostAddresses("127.0.0.1");
IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5655);
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
string filePath = "";
fileDes = fileDes.Replace("\", "/");
while (fileDes.IndexOf("/") > -1)
{
filePath += fileDes.Substring(0, fileDes.IndexOf("/") + 1);
fileDes = fileDes.Substring(fileDes.IndexOf("/") + 1);
}
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileDes);
lblError.Text = "";
lblError.Text = "Buffering ...";
byte[] fileData = File.ReadAllBytes(filePath + fileDes);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
lblError.Text = "";
lblError.Text = "Connection to server ...";
clientSock.Connect(ipEnd);
lblError.Text = "";
lblError.Text = "File sending...";
// System.Threading.Thread.Sleep(1000);
clientSock.Send(clientData);
label3.Text = clientData.Length.ToString();
lblError.Text = "";
lblError.Text = "Disconnecting...";
clientSock.Close();
lblError.Text = "";
lblError.Text = "File transferred.";
在客户端
class DestCode
{
IPEndPoint ipEnd;
Socket sock;
public DestCode()
{
ipEnd = new IPEndPoint(IPAddress.Any, 5656);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
}
public static string receivedPath;
public static string curMsg = "Stopped";
public static int res;
public void StartServer()
{
try
{
curMsg = "Starting...";
sock.Listen(100);
curMsg = "Running and waiting to receive file.";
Socket clientSock = sock.Accept();
byte[] clientData = new byte[1024 * 5000];
int receivedBytesLen = clientSock.Receive(clientData);
curMsg = "Receiving data...";
int fileNameLen = BitConverter.ToInt32(clientData, 0);
string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);
BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath +"/"+ fileName, FileMode.Append)); ;
bWrite.Write(clientData,4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
res = receivedBytesLen;
if (receivedPath == "")
{
MessageBox.Show("No Path was selected to Save the File");
}
curMsg = "Saving file...";
bWrite.Close();
clientSock.Close();
curMsg = "File Received ...";
StartServer();
}
catch (Exception ex)
{
curMsg = "File Receving error.";
}
}
}
贪心
class ReceiverCode
{
IPEndPoint ipEnd;
Socket sock;
public ReceiverCode()
{
ipEnd = new IPEndPoint(IPAddress.Any, 5655);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
}
public static string receivedPath;
public static string curMsg = "Stopped";
public static string Rout = "";
public static int rlength = 0;
public static string MsgStatus = "";
public static byte[] send;
public void StartServer()
{
try
{
curMsg = "Starting...";
sock.Listen(100);
curMsg = "Running and waiting to receive file.";
Socket clientSock = sock.Accept();
byte[] clientData = new byte[1024 * 5000];
int receivedBytesLen = clientSock.Receive(clientData);
System.Threading.Thread.Sleep(5000);
rlength = receivedBytesLen;
curMsg = "Receiving data...";
int receive = clientSock.Receive(clientData);
send = new byte[receivedBytesLen];
Array.Copy(clientData, send, receivedBytesLen);
Rout = "Start";
clientSock.Close();
curMsg = "Reeived & Saved file; Server Stopped.";
StartServer();
}
catch (Exception ex)
{
curMsg = "File Receving error.";
}
}
}
请有人帮助我
问题是 Socket.Receive
不能保证您会收到您要求的所有字节。所以你写:
int receivedBytesLen = clientSock.Receive(clientData);
If you are using a connection-oriented Socket, the Receive method will read as much data as is available, up to the size of the buffer.
对 Receive
的调用正在获取当前可用的所有字节。可能是发件人尚未发送所有字节,或者您的网络堆栈尚未收到并使它们可用。
为了可靠地发送和接收数据,接收方必须知道以下两件事之一:它期望有多少字节,或者有一些标记值表明,"that's all, folks." 你不能指望一次 Receive
调用即可获取所有内容。
传输文件时,发件人通常将文件的大小作为要发送的数据的前四个字节。然后您的代码读取前四个字节(确保您获得所有四个字节)以确定大小,然后旋转一个循环,从套接字读取数据,直到收到所有预期的字节。
类似于:
const int MaximumSize = 1000000;
// read the first four bytes
var sizeBytes = ReadBytesFromSocket(socket, 4);
int size = BitConverter.ToInt32(sizeBytes);
var dataBuffer = ReadBytesFromSocket(socket, size);
// you now have your data
byte[] ReadBytesFromSocket(Socket socket, int size)
{
var buff = new byte[size];
int totalBytesRead = 0;
while (totalBytesRead < size)
{
int bytesRead = socket.Receive(buff, totalBytesRead, size-totalBytesRead, SocketFlags.None);
if (bytesRead == 0)
{
// nothing received. The socket has been closed.
// maybe an error.
break;
}
totalBytesRead += bytesRead
}
return buff;
}
有关详细信息,请参阅我在 reading streams 上的博客 post(以及链接的第 1 部分和第 2 部分)。博客 post 讨论流,但概念与套接字相同。