我遇到了一点点并发症。
我可能不是TCP Connections的专家,但我希望有人能帮到我。
这是我的客户代码:
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());
}
}
}
}
}
我在这里尝试做什么: - 我希望客户端发送消息..如“SaveFile”&amp;在此字符串之后是filedata。 - 在对文件执行某些操作之前,服务器应该读取客户端消息并根据客户端sentstring处理内容。
我相信我不知道该怎么做。
我是否有一个关于如何从文件的开始发送/接收和读取某些字符串的示例?我怎么能把它们放在字节数组中以及如何读取它......这是非常压倒性的......
PS:当前的服务器代码正在读取数据,并且在我编码时写入CAN,而不会丢失任何软件包。但他也在编写我转换文件字节之前发送的附加数据包。
答案 0 :(得分:0)
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平台上实现。