Можно читать данные пока они есть, столько сколько их есть, не обязательно знать их длину. Рабочий пример (не для консоли, но сути не меняет)
Серверnamespace TCP_Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MethodInvoker mi = new MethodInvoker(delegate
{
int port = 999; //взяли порт из файла
TcpListener l = new TcpListener(port); //и на нем у нас висит сервер
l.Start(); //запущен
while (true)
{
TcpClient cl = l.AcceptTcpClient();
Connection c = new Connection();
c.cl = cl;
Thread t = new Thread(new ThreadStart(c.Work));
t.IsBackground = false;
t.Start();
}
});
mi.BeginInvoke(null, null);
}
private void Form1_Load(object sender, EventArgs e)
{
}
public class Connection
{
public TcpClient cl;
public void Work()
{
NetworkStream NWS = cl.GetStream();
//BinaryReader R = new BinaryReader(NWS); //принятие
//BinaryWriter W = new BinaryWriter(NWS); //отправка
if (NWS.CanRead)
{
StringBuilder fullServerReply = new StringBuilder();
byte[] readBuffer = new byte[cl.ReceiveBufferSize];
int numberOfBytesRead = 0;
do
{
numberOfBytesRead = NWS.Read(readBuffer, 0, readBuffer.Length);
fullServerReply.AppendFormat("{0}", Encoding.UTF8.GetString(readBuffer, 0, cl.ReceiveBufferSize));
} while (NWS.DataAvailable);
var s = fullServerReply.ToString();
Console.WriteLine(s); // тут твои данные
}
}
}
}
}
Клиент
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TCP_Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public int port = 999; //умолчание
public string adres = "127.0.0.1"; //умолчание
NetworkStream NWS;
BinaryReader R;
BinaryWriter W;
private void Form1_Load(object sender, EventArgs e)
{
reg();
}
private void reg()
{
//создадим сокетное подключение для общения с сервером
TcpClient client = new TcpClient(adres, port); //IP адрес сервера и порт на котором он висит
NWS = client.GetStream();
R = new BinaryReader(NWS); //поток для принятия данных
W = new BinaryWriter(NWS); //поток для отправки данных
//ну и тут ваше что-то
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
private void button1_Click(object sender, EventArgs e)
{
reg();
W.Write(textBox1.Text);
NWS.Flush();
}
}
}
Данные можно было бы упаковать в класс вместе с чек суммой и отправлять после сериализации, одновременно можно их еще и сжать (чтобы меньше пришлось передавать), вот пример реализации сериализации со сжатием:
string FileName = "Signes.db";
public void Save()
{
//Сохраняем резервную копию
if (File.Exists(FileName))
{
File.Copy(FileName, FileName + DateTime.Now.ToShortDateString() + ".bak", true);
}
BinaryFormatter bf = new BinaryFormatter();
//откроем поток для записи в файл
using (FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
using (GZipStream gz = new GZipStream(fs, CompressionMode.Compress, false))
{
bf.Serialize(gz, Signes);//сериализация
}
}
public void Load()
{
if (!File.Exists(FileName))
{
Signes = new List<BaseSign>(); //указать тип нового объекта
Save();
}
BinaryFormatter bf = new BinaryFormatter();
using (FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
using (GZipStream gz = new GZipStream(fs, CompressionMode.Decompress, false))
{
Signes = (List<BaseSign>)bf.Deserialize(gz); //указать тип объекта
}
}