如何确保我不会丢失来自TCP的数据?
问题描述:
对不起,如果我问一些问题之前。如何确保我不会丢失来自TCP的数据?
我正在开发一个程序,读取通过TCP接收的数据并使用StreamReader,而我无法找到如何确保不会丢失任何数据。有什么办法可以创建一个中间缓冲区来从那里读取或类似的东西?
这里是我创建的方法用于接收数据并将它写入一个文本框:
public static void Connect(string IP, string port)
{
try
{
client = new TcpClient();
IPEndPoint IP_End = new IPEndPoint(IPAddress.Parse(IP), int.Parse(port));
client.Connect(IP_End);
if (client.Connected)
{
connected = "Connected to Exemys!" + "\r\n";
STR = new StreamReader(client.GetStream());
bgWorker = true;
}
}
catch (Exception x)
{
MessageBox.Show(x.Message.ToString());
}
}
-
public static void MessageReceiving(TextBox textBox)
{
try
{
string values =Conection.STR.ReadLine();
textBox.Invoke(new MethodInvoker(delegate() { textBox.AppendText("Exemys : " + values.Substring(2) + Environment.NewLine); }));
try
{
string messagetype = values.Substring(5, 1);
string ID = values.Substring(3, 2);
string checksum = values.Substring(values.Length - 2, 2);
if (checksum == CalcularChecksum(values.Substring(3, values.Length - 5)))
{
if (messagetype == "N")
{
if (ID == "01")
{
ID1 = values.Substring(3, 2);
messagetype1 = values.Substring(5, 1);
capacity1 = values.Substring(6, 1);
pressure1 = values.Split(',')[1];
sequencetime1 = values.Split(',')[2];
runstatus1 = values.Split(',')[3];
mode1 = values.Split(',')[4].Substring(0, 1);
checksum1 = CalcularChecksum(values.Substring(3, values.Length - 5));
}
if (ID == "02")
{
ID2 = values.Substring(3, 2);
messagetype2 = values.Substring(5, 1);
capacity2 = values.Substring(6, 1);
pressure2 = values.Split(',')[1];
sequencetime2 = values.Split(',')[2];
runstatus2 = values.Split(',')[3];
mode2 = values.Split(',')[4].Substring(0, 1);
checksum2 = CalcularChecksum(values.Substring(3, values.Length - 5));
}
}
}
}
catch(Exception x)
{
MessageBox.Show(x.Message.ToString());
}
}
catch (Exception)
{
MessageBox.Show("Client disconnected.");
}
}
编辑:我想要问的是如何在继续接收之前总是处理整个数据?这将是一个问题。
答
TCP流是由您或远程对等关闭套接字或由于网络问题而中断时结束的字节流。为了从流中获取所有内容,您需要将循环内的StreamReader.ReadLine
方法调用到缓冲区中,直到应用某种停止条件。
...
try
{
while(true)
{
...
input = STR.ReadLine();
if (input == <some stop condition>)
break;
...
}
}
...
这是一个非常简化的例子。使用部分缓冲区处理的TCP读取可能是一个复杂的野兽,所以如果您不仅仅是一些业余爱好项目,我建议使用库或框架。
答
感谢您的回应,但经过搜索,我找到了我正在寻找的东西。我想存储那些正在输入的消息(数据),以确保我不会丢失它们(出于任何原因,更确切地说,接收过程将比消息处理操作更快),所以我使用Queue
来实现此目的。
public static void RecepcionMensajes(TextBox textBox)
{
if (client.Connected == true)
{
try
{
string fifo = Conexion.STR.ReadLine();
Queue mensajes = new Queue();
//Aquí se ponen en cola los mensajes que van llegando, utilizando el sistema FIFO.
mensajes.Enqueue(fifo);
string values = mensajes.Dequeue().ToString();
textBox.Invoke(new MethodInvoker(delegate() { textBox.AppendText("Exemys : " + values.Substring(2) + Environment.NewLine); }));
添加控制字节。例如。每32/64个字节增加2个字节。如果他们不在那里 - 缺少一些东西。 – i486