class FixedRecieveFilterX : FixedHeaderReceiveFilter<DataPackageInfo>
{
public FixedRecieveFilterX()
: base(4)
{
}
public override DataPackageInfo ResolvePackage(IBufferStream bufferStream){
bufferStream.Skip(4);
return new DataPackageInfo(){
Data = (Message)new BinaryFormatter().Deserialize(bufferStream.GetCurrentStream())
};
}
protected override int GetBodyLengthFromHeader(IBufferStream bufferStream, int length)
{
byte[] head = new byte[4];
bufferStream.Read(head,0,4);
return BitConverter.ToInt32(head, 0);
}
}
public class DataFixedRecieveFilter: FixedHeaderReceiveFilter<DataRequestInfo>
{
public DataFixedRecieveFilter() : base(4){
}
protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length){
return BitConverter.ToInt32(header,offset);
}
protected override DataRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(bodyBuffer,offset,length);
ms.Seek(0, SeekOrigin.Begin);
BinaryFormatter bf = new BinaryFormatter();
Message msg = (Message) bf.Deserialize(ms);
return new DataRequestInfo(){
Key = msg.key,
message = msg
};
}
}
}
class DataRecieveFilter : IReceiveFilter<DataRequestInfo> {
private byte[] reserveBuff;
public DataRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) {
byte[] localBuffer = new byte[length];
if (reserveBuff != null && reserveBuff.Length > 0){
localBuffer = new byte[reserveBuff.Length + length];
Buffer.BlockCopy(reserveBuff, 0, localBuffer, 0, reserveBuff.Length);
Buffer.BlockCopy(readBuffer, offset, localBuffer, reserveBuff.Length, length);
reserveBuff = null;
}
else
Buffer.BlockCopy(readBuffer,offset,localBuffer,0,length);
if (localBuffer.Length > 4){
byte[] head = new byte[4];
Buffer.BlockCopy(localBuffer, 0, head, 0, 4);
int sizeContent = BitConverter.ToInt32(head, 0);
if (localBuffer.Length >= sizeContent + 4){
BinaryFormatter formatter = new BinaryFormatter();
byte[] dataMessage = new byte[sizeContent];
Buffer.BlockCopy(localBuffer, 4, dataMessage, 0, sizeContent);
using (MemoryStream msTemp = new MemoryStream(dataMessage)){
Message msg = (Message) formatter.Deserialize(msTemp);
rest = localBuffer.Length - sizeContent - 4;
return new DataRequestInfo()
{
Key = msg.key,
message = msg
};
}
}
}
rest = 0;
reserveBuff = localBuffer;
return null;
}
public void Reset()
{
reserveBuff = null;
}
public int LeftBufferSize { get; set; }
public IReceiveFilter<DataRequestInfo> NextReceiveFilter { get; set; }
public FilterState State { get; set; }
}
class ServerMain
{
static void Main(string[] args) {
TcpListener listener = new TcpListener(IPAddress.Any, 2255);
listener.Start(100);//Запускаем сервер, слушаем порт 2255
Console.WriteLine("Listen 2255");
while (true){
new ClientSocket(listener.AcceptSocket());//Ждем подключения клиента, при подключении создаем новый класс ClientSocket
Console.WriteLine("Socket connect");//Сокет подключен, ждем других клиентов
}
}
}
public class ClientSocket{
private Socket socket;
private MemoryStream recieveData = new MemoryStream();
public const int BufferSize = 512; //Размер буфера
byte[] buffer = new byte[BufferSize];
public ClientSocket(Socket s){
this.socket = s;
socket.BeginReceive(this.buffer, 0, ClientSocket.BufferSize, 0, new AsyncCallback(ReceiveCallback), this);
}
private void RecieveMessage(Message msg) {//Вызывается когда получили запрос от клиента
Console.WriteLine("Recieve: {0} {1} {2}", msg.id, msg.title, msg.message);//выводим на экран
msg.title = "ответ";
msg.message = "hi";
this.SendMessage(msg);//отправим ответ клиенту
}
private static void ReceiveCallback(IAsyncResult ar){
ClientSocket state = (ClientSocket)ar.AsyncState;
Socket client = state.socket;
int bytesRead = 0;
try{
bytesRead = client.EndReceive(ar);//количество байт записанных в буффер
}
catch (SocketException se){
if (se.ErrorCode == 10054){
Console.WriteLine("Клиент отключился");
return;
}
else
throw se;
}
if (bytesRead > 0){
state.recieveData.Write(state.buffer, 0, bytesRead);//пишет в поток принятых байт
Console.WriteLine("read {0} byte, available {1}", bytesRead, client.Available);
}
// ОБРАБОТКА ПОТОКА
while(state.recieveData.Length > 4) {//обрабатываем поток пока там его длинна больше нашего заголовка, длинна 4 потому-что int занимает 4 байта, это заголовок
state.recieveData.Seek(0, SeekOrigin.Begin);//Ставим указатель в начало поток, потому что read читает от указателя, это тупо
byte[] head = new byte[4];//Буфер для заголовка
state.recieveData.Read(head, 0, 4);//записываем заголовок (размер сообщения) в буффер
int sizeContent = BitConverter.ToInt32(head, 0);//Заголовок содержит длину Message в байтах, которую Message занимает после заголовка
if (state.recieveData.Length >= sizeContent + 4) { //Если мы приняли данных уже на длинну сообщений + длинну заголовка, значит можно достать данные
IFormatter formatter = new BinaryFormatter();
byte[] dataMessage = new byte[sizeContent];//Создаем буффер для сообщения
state.recieveData.Seek(4, SeekOrigin.Begin);//Ставим указатель в потоке на начало нашего сообщения ( 1байт после заголовка)
state.recieveData.Read(dataMessage, 0, sizeContent);//Пишем наше сообщение в буфер
using (MemoryStream msTemp = new MemoryStream(dataMessage)) //Создаем временный поток и пишем в него сообщения для десереализации
state.RecieveMessage((Message)formatter.Deserialize(msTemp));//десереализируем сообщения и передаем методу recievemesssage
//Далее на нужно удалить из потока наш заголовок + данные
if (state.recieveData.Length - sizeContent - 4 > 0) {//Если у нас в потоке еще остались данные кроме тех что мы прочитали
byte[] dataOther = new byte[state.recieveData.Length - sizeContent - 4];//Создаем буффер для оставшихся
state.recieveData.Seek(sizeContent + 4, SeekOrigin.Begin);//ставим указатель в потоке на начало оставшихся данных
state.recieveData.Read(dataOther, 0, dataOther.Length);//записываем оставшиеся данные в буффер
state.recieveData.SetLength(0);//сбрасываем поток...
state.recieveData.Write(dataOther,0,dataOther.Length);//записываем в поток оставшиеся данные
state.recieveData.Seek(0, SeekOrigin.End);//ставим указатель в конец потока на всякий случай
}
else//Если в потоке больше нет данных
state.recieveData.SetLength(0);//сбрасываем поток...
}
else { //Иначе если мы приняли данных меньше чем длинна сообщений + длинна заголовка, значит выходим из цикла, нам нужно еще чуть чуть принять
state.recieveData.Seek(0, SeekOrigin.End);//ставим указатель в конец потока на всякий случай
break;
}
}
client.BeginReceive(state.buffer, 0, ClientSocket.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);//ждем еще данные
}
public void SendMessage(Message msg) {//Послать сообщение клиенту
using (MemoryStream ms = new MemoryStream()) {
ms.WriteByte(0);
ms.WriteByte(0);
ms.WriteByte(0);
ms.WriteByte(0);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, msg);
ms.Seek(0, SeekOrigin.Begin);
ms.Write(BitConverter.GetBytes(ms.Length-4),0,4);
ms.Seek(0, SeekOrigin.End);
socket.BeginSend(ms.GetBuffer(), 0, (int) ms.Length, 0, ar => {
(ar.AsyncState as ClientSocket).socket.EndSend(ar);
Console.WriteLine("Сообщение отправлено клиенту");
}, this);
}
}
~ClientSocket()
{
if (recieveData != null)
{
recieveData.Close();
recieveData.Dispose();
}
}
}
[Serializable]
public class Message {
public int id;
public string title;
public string message;
}
class ClientMain
{
private static TcpClient client;
private static MemoryStream recieveData = new MemoryStream();
public const int BufferSize = 512; //Размер буфера
public static byte[] buffer = new byte[BufferSize];
static void Main(string[] args){
client = new TcpClient("127.0.0.1",2255);//Коннект к серверу
client.Client.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReceiveCallback), null);//Приготовились принимать данные
for (int i = 0; i < 10; i++)//Шлём сообщения серверу
SendMessage(new Message() {
id = i,
message = "Hello world",
title = "My Title"
});
Console.ReadKey();
}
private static void RecieveMessage(Message msg) {//Вызывается когда получили ответ от сервера
Console.WriteLine("Ответ сервера: {0} {1} {2}", msg.id, msg.title, msg.message);
}
public static void SendMessage(Message msg) {//Послать сообщение серверу
using (MemoryStream ms = new MemoryStream()) {
ms.WriteByte(0);
ms.WriteByte(0);
ms.WriteByte(0);
ms.WriteByte(0);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, msg);
ms.Seek(0, SeekOrigin.Begin);
ms.Write(BitConverter.GetBytes(ms.Length - 4), 0, 4);
ms.Seek(0, SeekOrigin.End);
ClientMain.client.Client.BeginSend(ms.GetBuffer(), 0, (int)ms.Length, 0, ar => {
ClientMain.client.Client.EndSend(ar);
Console.WriteLine("Сообщение отправлено серверу");
}, null);
}
}
private static void ReceiveCallback(IAsyncResult ar) {
Socket client = ClientMain.client.Client;
int bytesRead = 0;
try {
bytesRead = client.EndReceive(ar);//количество байт записанных в буффер
}
catch (SocketException se)
{
if (se.ErrorCode == 10054)
{
Console.WriteLine("Потеря соединения с сервером");
return;
}
else
throw se;
}
if (bytesRead > 0)
ClientMain.recieveData.Write(ClientMain.buffer, 0, bytesRead);
// ОБРАБОТКА ПОТОКА
while (ClientMain.recieveData.Length > 4) {
ClientMain.recieveData.Seek(0, SeekOrigin.Begin);
byte[] head = new byte[4];
ClientMain.recieveData.Read(head, 0, 4);
int sizeContent = BitConverter.ToInt32(head, 0);
if (ClientMain.recieveData.Length >= sizeContent + 4) {
IFormatter formatter = new BinaryFormatter();
byte[] dataMessage = new byte[sizeContent];
ClientMain.recieveData.Seek(4, SeekOrigin.Begin);
ClientMain.recieveData.Read(dataMessage, 0, sizeContent);
using (MemoryStream msTemp = new MemoryStream(dataMessage))
RecieveMessage((Message) formatter.Deserialize(msTemp));
if (ClientMain.recieveData.Length - sizeContent - 4 > 0) {
byte[] dataOther = new byte[ClientMain.recieveData.Length - sizeContent - 4];
ClientMain.recieveData.Seek(sizeContent + 4, SeekOrigin.Begin);
ClientMain.recieveData.Read(dataOther, 0, dataOther.Length);
ClientMain.recieveData.SetLength(0);
ClientMain.recieveData.Write(dataOther, 0, dataOther.Length);
ClientMain.recieveData.Seek(0, SeekOrigin.End);
}
else
ClientMain.recieveData.SetLength(0);
}
else {
ClientMain.recieveData.Seek(0, SeekOrigin.End);
break;
}
}
client.BeginReceive(ClientMain.buffer, 0, ClientMain.BufferSize, 0,
new AsyncCallback(ReceiveCallback), null);//ждем еще данные
}
}
MemoryStream msTemp
class ClientMain{
static void Main(string[] args){
TcpClient client = new TcpClient("127.0.0.1",2255);//Коннект к серверу
for (int i = 0; i < 100; i++){//Шлём 100 сообщений
using (var stream = new NetworkStream(client.Client)){//Берем поток сокета
BinaryFormatter bf = new BinaryFormatter();
var msg = new Message(){//Создаем сообщение которое хотим послать на сервер
id = i,
message = "Hello world",
title = "My Title"
};
using (MemoryStream ms = new MemoryStream()){
bf.Serialize(ms, msg);//сериализуем и пишем в поток
var arr = ms.GetBuffer();
stream.Write(BitConverter.GetBytes(arr.Length),0,4);//Записываем длинну буфера,естественно длинна буфер не должна быть больше Int32.MaxValue (2147483647) это ~ 2гига
stream.Write(arr,0,arr.Length);//Записываем сам буффер
}
}
//Thread.Sleep(100); //Если добавить задержку то всё ок
}
Console.WriteLine("end");
Console.ReadKey();
}
}
public class ClientSocket{
private Socket socket;
private MemoryStream recieveData = new MemoryStream();
public const int BufferSize = 8096;
byte[] buffer = new byte[BufferSize];
public ClientSocket(Socket s){
this.socket = s;
socket.BeginReceive(this.buffer, 0, ClientSocket.BufferSize, 0, new AsyncCallback(ReceiveCallback), this);
}
private static void ReceiveCallback(IAsyncResult ar){
ClientSocket state = (ClientSocket)ar.AsyncState;
Socket client = state.socket;
int bytesRead = 0;
try{
bytesRead = client.EndReceive(ar);//количество байт записанных в буффер
}
catch (SocketException se){
if (se.ErrorCode == 10054){
Console.WriteLine("Клиент отключился");
return;
}
else
throw se;
}
if (bytesRead > 0){
state.recieveData.Write(state.buffer, 0, bytesRead);//пишет в поток принятых байт
Console.WriteLine("read {0} byte, available {1}", bytesRead, client.Available);
}
// ОБРАБОТКА ПОТОКА
while(state.recieveData.Length > 4) {//обрабатываем поток пока там его длинна больше нашего заголовка, длинна 4 потому-что int занимает 4 байта, это заголовок
state.recieveData.Seek(0, SeekOrigin.Begin);//Ставим указатель в начало поток, потому что read читает от указателя, это тупо
byte[] head = new byte[4];//Буфер для заголовка
state.recieveData.Read(head, 0, 4);//записываем заголовок (размер сообщения) в буффер
int sizeContent = BitConverter.ToInt32(head, 0);//Заголовок содержит длину Message в байтах, которую Message занимает после заголовка
if (state.recieveData.Length >= sizeContent + 4) { //Если мы приняли данных уже на длинну сообщений + длинну заголовка, значит можно достать данные
IFormatter formatter = new BinaryFormatter();
byte[] dataMessage = new byte[sizeContent];//Создаем буффер для сообщения
state.recieveData.Seek(4, SeekOrigin.Begin);//Ставим указатель в потоке на начало нашего сообщения ( 1байт после заголовка)
state.recieveData.Read(dataMessage, 0, sizeContent);//Пишем наше сообщение в буфер
using (MemoryStream msTemp = new MemoryStream(dataMessage)) {//Создаем временный поток и пишем в него сообщения для десереализации
Message msg = (Message)formatter.Deserialize(msTemp);//десереализируем сообщений
Console.WriteLine("Recieve: {0} {1} {2}", msg.id, msg.title, msg.message);//выводим на экран
}
//Далее на нужно удалить из потока наш заголовок + данные
if (state.recieveData.Length - sizeContent - 4 > 0) {//Если у нас в потоке еще остались данные кроме тех что мы прочитали
byte[] dataOther = new byte[state.recieveData.Length - sizeContent - 4];//Создаем буффер для оставшихся
state.recieveData.Seek(sizeContent + 4, SeekOrigin.Begin);//ставим указатель в потоке на начало оставшихся данных
state.recieveData.Read(dataOther, 0, dataOther.Length);//записываем оставшиеся данные в буффер
state.recieveData.SetLength(0);//сбрасываем поток...
state.recieveData.Write(dataOther,0,dataOther.Length);//записываем в поток оставшиеся данные
state.recieveData.Seek(0, SeekOrigin.End);//ставим указатель в конец потока на всякий случай
}
else//Если в потоке больше нет данных
state.recieveData.SetLength(0);//сбрасываем поток...
}
else { //Иначе если мы приняли данных меньше чем длинна сообщений + длинна заголовка, значит выходим из цикла, нам нужно еще чуть чуть принять
state.recieveData.Seek(0, SeekOrigin.End);//ставим указатель в конец потока на всякий случай
break;
}
}
client.BeginReceive(state.buffer, 0, ClientSocket.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);//ждем еще данные
}
~ClientSocket()
{
if (recieveData != null)
{
recieveData.Close();
recieveData.Dispose();
}
}
}
VideoCard[0].SetActive(true);
добавляй проверку на размер массива.Тут же нужно создать массив и инициализовать его, добавить элементы. Ну я так понимаю за это отвечает метод Load который по идее должен формировать массив, значит или здесь что-то не так , так как создается пустой массив или вообще удалите метод Load, может это массив инициализирует инспектор где-то....