有一天,我有一个惊人的"我的 C#应用程序的想法。我没有为每种数据类型使用一个端口(文本,图像,文件),而是希望对所有三种数据类型使用单一端口。我非常接近实施这个。
到目前为止,我有一个 TcpListener 正在侦听端口 23722 。当 TcpClient 连接时,我开始使用StreamWriter.Write(datareceived);
将传入数据写入文件,并且数据以特定模式出现(每行代表图像,文本消息或文件):
dnett {这是示例短信。)
dneti {NLtqmuvtGBdDY546 ... NLtqmuvtGBdDY546}
dnetf {Example.exe,NLtqmuvtGBdDY546 ... NLtqmuvtGBdDY546}
正如您在上面看到的图像和文件在发送之前转换为Base64 。要将它们转换回来,我会使用byte[] tmp = Convert.FromBase64String(string)
,但问题是我无法逐行读取文件,而数据仍在传入(使用写入) StreamWriter的)。另一个问题是,我不知道哪些数据已被处理(例如:哪些文件已经写入文件系统)。
或
顺便说一下,我只有15岁,而英语不是我的第一语言,所以我很抱歉可能存在愚蠢的问题以及上述问题的错误。
答案 0 :(得分:0)
我也是初学者。但我认为您可以使用ArrayList来转换所有行,直到所有行都被引用和发送。因此,当你准备好了,文件全部被引用时,yoy可以保存它。如果您询问如何知道识别哪种文件被发送,请先发送文件,您可以发送一个字符或字符串,允许其他程序等待文件识别该文件将被恢复。对不起我的英语。我希望我能帮到你。
答案 1 :(得分:0)
通常,您首先会发送"消息的大小"然后是实际的"消息" (来自服务器)。您可以将其扩展为首先发送消息类型的大小,然后发送消息类型,然后发送实际消息的大小,然后发送该消息。
要回头看,你可以这样做
using System;
using System.IO;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using Newtonsoft.Json;
using Unity3DRemoteRendererClient.Helpers;
namespace Unity3DRemoteRendererClient.Communications.TCPCommunication {
public sealed partial class TCPClientManager {
public sealed class Receiver {
private NetworkStream _stream;
private Thread _thread;
//Subscribe to this event if you want an event ever time data arrives.
public event EventHandler < UnityToClientMessage > DataReceivedEvent;
private static ManualResetEvent ShutDownEvent = new ManualResetEvent(false);
public void Start(NetworkStream stream) {
_stream = stream;
_thread = new Thread(Run);
_thread.Start();
}
private void Run() {
try {
// ShutdownEvent is a ManualResetEvent signaled by
// Client when its time to close the socket.
while (!ShutDownEvent.WaitOne(0)) {
try {
if (!_stream.DataAvailable) continue;
//Read the first 4 bytes which represent the size of the message, and convert from byte array to int32
var sizeinfo = new byte[4];
_stream.Read(sizeinfo, 0, 4);
var messageSize = BitConverter.ToInt32(sizeinfo, 0);
//create a new buffer for the data to be read
var buffer = new byte[messageSize];
var read = 0;
//Continue reading from the stream until we have read all bytes @messageSize
while (read != messageSize) {
read += _stream.Read(buffer, read, buffer.Length - read);
}
//I use flatbuffers, so you should deserialize yourself.
var message = new UnityToClientMessage().FlatDeserialize(buffer);
//raise data received event
OnDataReceived(message);
} catch (IOException ex) {
// Handle the exception...
throw;
}
}
} catch (Exception ex) {
// Handle the exception...
throw;
} finally {
_stream.Close();
}
}
private void OnDataReceived(UnityToClientMessage e) {
EventHandler < UnityToClientMessage > handler = DataReceivedEvent;
if (handler != null) {
handler(this, e);
}
}
public void ShutDown() {
ShutDownEvent.Set();
}
}
}
}
只需将其修改为首先读取消息类型消息的大小,然后再读取实际消息。一旦获得描述消息类型的消息,就可以执行switch语句,并相应地处理它。