C# TCPListener文件传输
我遇到了一点小麻烦 我可能不是TCP连接方面的专家,但我希望这里有人能帮助我 这是我的客户代码:C# TCPListener文件传输,c#,tcpclient,C#,Tcpclient,我遇到了一点小麻烦 我可能不是TCP连接方面的专家,但我希望这里有人能帮助我 这是我的客户代码: void Connect(String server, String message) { try { Int32 port = 8968; TcpClient client = new TcpClient(server, port); Byte[] data = File.Rea
void Connect(String server, String message)
{
try
{
Int32 port = 8968;
TcpClient client = new TcpClient(server, port);
Byte[] data = File.ReadAllBytes(curSelectedFile);
NetworkStream stream = client.GetStream();
Byte[] fileData = File.ReadAllBytes(curSelectedFile);
Byte[] msgData = Encoding.ASCII.GetBytes("SendFile");
Byte[] sendData = new byte[fileData.Length + msgData.Length];
// Copy data to send package.
msgData.CopyTo(sendData, 0);
fileData.CopyTo(sendData, 4);
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent: {0}", message);
// Receive the TcpServer.response.
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}", responseData);
// Close everything.
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("\n Press Enter to continue...");
Console.Read();
}
这是我的服务器一:
// Listen loop.
while(true)
{
using (TcpClient tcpClient = myListener.AcceptTcpClient())
{
Console.WriteLine("[Server] Acceptam client.");
using (NetworkStream networkStream = tcpClient.GetStream())
{
// Buffer for reading data
Byte[] bytes = new Byte[1024];
var data = new List<byte>();
int length;
while ((length = networkStream.Read(bytes, 0, bytes.Length)) != 0)
{
var copy = new byte[length];
Array.Copy(bytes, 0, copy, 0, length);
data.AddRange(copy);
}
// Incercam sa vedem ce doreste clientul.
string msg = Encoding.ASCII.GetString(data[0], 0, length);
if(msg.StartsWith("SendFile"))
{
using (Stream stream = new FileStream(@"C:\test.mp3", FileMode.Create, FileAccess.ReadWrite))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
networkStream.Position = 4;
binaryFormatter.Serialize(networkStream, data.ToArray());
}
}
}
}
}
//侦听循环。
while(true)
{
使用(TcpClient TcpClient=myListener.AcceptTcpClient())
{
Console.WriteLine(“[Server]acceptim客户端”);
使用(NetworkStream NetworkStream=tcpClient.GetStream())
{
//用于读取数据的缓冲区
字节[]字节=新字节[1024];
var data=新列表();
整数长度;
while((长度=networkStream.Read(bytes,0,bytes.length))!=0)
{
var copy=新字节[长度];
复制(字节,0,复制,0,长度);
数据。添加范围(副本);
}
//因为这是一部电影。
string msg=Encoding.ASCII.GetString(数据[0],0,长度);
if(msg.StartsWith(“SendFile”))
{
使用(Stream-Stream=newfilestream(@“C:\test.mp3”、FileMode.Create、FileAccess.ReadWrite))
{
BinaryFormatter BinaryFormatter=新的BinaryFormatter();
networkStream.Position=4;
序列化(networkStream,data.ToArray());
}
}
}
}
}
我在这里要做的是:
-我希望客户发送一条消息。。像“SaveFile”&在这个字符串之后是filedata。
-在处理文件之前,服务器应该读取客户机消息,并根据客户机sentstring处理内容
我相信我不知道怎么做
我可以举一个例子说明如何发送/接收和读取文件中的某些字符串吗?如何将它们放入字节数组以及如何读取。。。这真是太难了
PS:当前的服务器代码正在读取数据,可以按照我的编码进行写入,而不会丢失任何包。但他也在写我在转换文件字节之前发送的传统数据包。
networkStream.Position=4代码>不合法,因为NetworkStream
不可查找
我不鼓励您混合使用文本和二进制数据,因为这会使应用程序协议变得复杂。但是如果您真的想这样做,您应该使用BinaryWriter
和BinaryReader
,因为它可以将字符串写入流中,以后可以读取该字符串,而无需占用字符串后面的字节
然后你可以做这样的事情
在客户端:
BinaryWriter writer = new BinaryWriter(networkStream);
writer.Write("SendFile");
writer.Write(fileData.Length);
writer.Write(fileData);
在服务器中:
BinaryReader reader = new BinaryReader(networkStream);
switch (reader.ReadString())
{
case "SendFile":
{
int length = reader.ReadInt32();
byte[] fileData = reader.ReadBytes(length);
// ... then do whatever with fileData, like write to a file
break;
}
}
长度计数字符串的BinaryWriter/Reader
实现是非标准的,因此,如果您想使用此技术与任何其他非.NET代码交互,它将更加复杂,因为您必须自己复制/重新实现非标准长度计数逻辑
更好的方法是将命令编码为固定长度的数据,例如8、16或32位的值,它只是指定命令的某个整数。然后,您可以在代码中以enum
类型列出您的命令,在网络流中强制转换I/O。这将更便于移植,更易于在非.NET平台上实现。感谢您的建议,我将尽可能避免在同一数组中传输字符串和二进制文件。